ky

  • Version 2.0.2
  • Published
  • 405 kB
  • No dependencies
  • MIT license

Install

npm i ky
yarn add ky
pnpm add ky

Overview

Tiny and elegant HTTP client based on the Fetch API

Index

Variables

variable ky

const ky: KyInstance;

    Functions

    function isForceRetryError

    isForceRetryError: (error: unknown) => error is ForceRetryError;
    • Type guard to check if an error is a ForceRetryError.

      Parameter error

      The error to check

      Returns

      true if the error is a ForceRetryError, false otherwise

      Example 1

      import ky, {isForceRetryError} from 'ky';
      const api = ky.extend({
      hooks: {
      beforeRetry: [
      ({error, retryCount}) => {
      if (isForceRetryError(error)) {
      console.log(`Forced retry #${retryCount}: ${error.code}`);
      }
      }
      ]
      }
      });

    function isHTTPError

    isHTTPError: <T = unknown>(error: unknown) => error is HTTPError<T>;
    • Type guard to check if an error is an HTTPError.

      Parameter error

      The error to check

      Returns

      true if the error is an HTTPError, false otherwise

      Example 1

      import ky, {isHTTPError} from 'ky';
      try {
      const response = await ky.get('/api/data');
      } catch (error) {
      if (isHTTPError(error)) {
      console.log('HTTP error status:', error.response.status);
      }
      }

    function isKyError

    isKyError: (error: unknown) => error is KyError;
    • Type guard to check if an error is a KyError.

      Note: SchemaValidationError is intentionally not considered a Ky error. KyError covers failures in Ky's HTTP lifecycle (bad status, timeout, retry), while schema validation errors originate from the user-provided schema, not from Ky itself.

      Parameter error

      The error to check

      Returns

      true if the error is a Ky error, false otherwise

      Example 1

      import ky, {isKyError} from 'ky';
      try {
      const response = await ky.get('/api/data');
      } catch (error) {
      if (isKyError(error)) {
      // Handle Ky-specific errors
      console.log('Ky error occurred:', error.message);
      } else {
      // Handle other errors
      console.log('Unknown error:', error);
      }
      }

    function isNetworkError

    isNetworkError: (error: unknown) => error is NetworkError;
    • Type guard to check if an error is a NetworkError.

      Parameter error

      The error to check

      Returns

      true if the error is a NetworkError, false otherwise

      Example 1

      import ky, {isNetworkError} from 'ky';
      try {
      const response = await ky.get('/api/data');
      } catch (error) {
      if (isNetworkError(error)) {
      console.log('Network error:', error.request.url);
      }
      }

    function isTimeoutError

    isTimeoutError: (error: unknown) => error is TimeoutError;
    • Type guard to check if an error is a TimeoutError.

      Parameter error

      The error to check

      Returns

      true if the error is a TimeoutError, false otherwise

      Example 1

      import ky, {isTimeoutError} from 'ky';
      try {
      const response = await ky.get('/api/data', { timeout: 1000 });
      } catch (error) {
      if (isTimeoutError(error)) {
      console.log('Request timed out:', error.request.url);
      }
      }

    function replaceOption

    replaceOption: <T>(value: T) => T;
    • Wraps a value so that ky.extend() will replace the parent value instead of merging with it. Works with hooks, headers, search parameters, context, and any other deep-merged option.

      By default, .extend() deep-merges options with the parent instance: hooks get appended, headers get merged, and search parameters get accumulated. Use replaceOption when you want to fully replace a merged property instead.

      Example 1

      import ky, {replaceOption} from 'ky';
      const base = ky.create({
      hooks: {beforeRequest: [addAuth, addTracking]},
      });
      // Replaces instead of appending
      const extended = base.extend({
      hooks: replaceOption({beforeRequest: [onlyThis]}),
      });
      // hooks.beforeRequest is now [onlyThis], not [addAuth, addTracking, onlyThis]

    Classes

    class ForceRetryError

    class ForceRetryError extends KyError {}
    • Error used to signal a forced retry from afterResponse hooks.

      This is thrown when ky.retry() is returned from an afterResponse hook. It is observable in beforeRetry and beforeError hooks via the isForceRetryError() type guard.

    constructor

    constructor(options?: ForceRetryOptions);

      property code

      code: string;

        property customDelay

        customDelay: number;

          property customRequest

          customRequest: Request;

            property name

            name: string;

              class HTTPError

              class HTTPError<T = unknown> extends KyError {}
              • Error thrown when the response has a non-2xx status code and throwHttpErrors is enabled.

                The error has a response property with the Response object, a request property with the Request object, an options property with the normalized options (either passed to ky when creating an instance with ky.create() or directly when performing the request), and a data property with the pre-parsed response body. For JSON responses (based on Content-Type), the body is parsed using the parseJson option if set, or JSON.parse by default. For other content types, it is set as plain text. If the body is empty or parsing fails, data will be undefined. To avoid hanging or excessive buffering, error.data population is bounded by the request timeout and a 10 MiB response body size limit. The data property is populated before beforeError hooks run, so hooks can access it.

                The response body is automatically consumed when populating error.data, so error.response.json() and other body methods will not work. Use error.data instead. The error.response object is still available for headers, status, etc.

                Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In that case, the error will be an instance of NetworkError instead of HTTPError and will not contain a response property.

              constructor

              constructor(response: Response, request: Request, options: NormalizedOptions);

                property data

                data: string | T;

                  property name

                  name: string;

                    property options

                    options: NormalizedOptions;

                      property request

                      request: KyRequest<unknown>;

                        property response

                        response: KyResponse<T>;

                          class KyError

                          class KyError extends Error {}
                          • Base class for all Ky-specific errors. HTTPError, NetworkError, TimeoutError, and ForceRetryError extend this class.

                            You can use instanceof KyError to check if an error originated from Ky, or use the isKyError() type guard for cross-realm compatibility and TypeScript type narrowing.

                            Note: SchemaValidationError is intentionally not considered a Ky error. KyError covers failures in Ky's HTTP lifecycle (bad status, timeout, retry), while schema validation errors originate from the user-provided schema, not from Ky itself.

                          property isKyError

                          readonly isKyError: boolean;

                            property name

                            name: string;

                              class NetworkError

                              class NetworkError extends KyError {}
                              • Error thrown when a network error occurs during the request (e.g., DNS failure, connection refused, offline). It has a request property with the Request object. The original error is available via the standard cause property.

                                Network errors are automatically retried (for retriable methods).

                                Note: Network errors are detected using runtime-specific heuristics. Unrecognized runtimes may produce errors that are not wrapped in NetworkError. Use the shouldRetry option to handle such cases.

                              constructor

                              constructor(request: Request, options?: { cause?: Error });

                                property name

                                name: string;

                                  property request

                                  request: KyRequest<unknown>;

                                    class SchemaValidationError

                                    class SchemaValidationError extends Error {}
                                    • The error thrown when [Standard Schema](https://github.com/standard-schema/standard-schema) validation fails in .json(schema). It has an issues property with the validation issues from the schema.

                                      This error intentionally does not extend KyError because it does not represent a failure in Ky's HTTP lifecycle. The request succeeded; the user's schema rejected the data. As such, it is not matched by isKyError().

                                      Example 1

                                      import ky, {SchemaValidationError} from 'ky';
                                      import {z} from 'zod';
                                      const userSchema = z.object({name: z.string()});
                                      try {
                                      const user = await ky('/api/user').json(userSchema);
                                      console.log(user.name);
                                      } catch (error) {
                                      if (error instanceof SchemaValidationError) {
                                      console.error(error.issues);
                                      }
                                      }

                                    constructor

                                    constructor(issues: readonly StandardSchemaV1Issue[]);

                                      property issues

                                      readonly issues: readonly StandardSchemaV1Issue[];

                                        property name

                                        name: string;

                                          class TimeoutError

                                          class TimeoutError extends KyError {}
                                          • Error thrown when the request times out. It has a request property with the Request object.

                                          constructor

                                          constructor(request: Request);

                                            property name

                                            name: string;

                                              property request

                                              request: KyRequest<unknown>;

                                                Interfaces

                                                interface NormalizedOptions

                                                interface NormalizedOptions extends RequestInit {}
                                                • Normalized options passed to the fetch call and hooks.

                                                property baseUrl

                                                baseUrl?: Options['baseUrl'];

                                                  property context

                                                  context: Record<string, unknown>;

                                                    property credentials

                                                    credentials?: NonNullable<RequestInit['credentials']>;

                                                      property method

                                                      method: NonNullable<RequestInit['method']>;

                                                        property onDownloadProgress

                                                        onDownloadProgress: Options['onDownloadProgress'];

                                                          property onUploadProgress

                                                          onUploadProgress: Options['onUploadProgress'];

                                                            property prefix

                                                            prefix: string;

                                                              property retry

                                                              retry: RetryOptions;

                                                                interface Options

                                                                interface Options extends KyOptions, Omit<RequestInit, 'headers'> {}
                                                                • Options are the same as window.fetch, except for the KyOptions

                                                                property headers

                                                                headers?: KyHeadersInit;
                                                                • HTTP headers used to make the request.

                                                                  You can pass a Headers instance or a plain object.

                                                                  You can remove a header with .extend() by passing the header with an undefined value. Passing undefined as a string removes the header only if it comes from a Headers instance.

                                                                  Example 1

                                                                  ``` import ky from 'ky';

                                                                  const url = 'https://sindresorhus.com';

                                                                  const original = ky.create({ headers: { rainbow: 'rainbow', unicorn: 'unicorn' } });

                                                                  const extended = original.extend({ headers: { rainbow: undefined } });

                                                                  const response = await extended(url).json();

                                                                  console.log('rainbow' in response); //=> false

                                                                  console.log('unicorn' in response); //=> true ```

                                                                property method

                                                                method?: LiteralUnion<HttpMethod, string>;
                                                                • HTTP method used to make the request.

                                                                  Internally, the standard methods (GET, POST, PUT, PATCH, HEAD and DELETE) are uppercased in order to avoid server errors due to case sensitivity.

                                                                Type Aliases

                                                                type AfterResponseHook

                                                                type AfterResponseHook = (
                                                                state: AfterResponseState
                                                                ) => Response | RetryMarker | void | Promise<Response | RetryMarker | void>;

                                                                  type AfterResponseState

                                                                  type AfterResponseState = {
                                                                  request: KyRequest;
                                                                  options: NormalizedOptions;
                                                                  response: KyResponse;
                                                                  /**
                                                                  The number of retries attempted. `0` for the initial request, increments with each retry.
                                                                  This allows you to distinguish between the initial request and retries, which is useful when you need different behavior for retries (e.g., showing a notification only on the final retry).
                                                                  */
                                                                  retryCount: number;
                                                                  };

                                                                    type BeforeErrorHook

                                                                    type BeforeErrorHook = (state: BeforeErrorState) => Error | Promise<Error>;

                                                                      type BeforeErrorState

                                                                      type BeforeErrorState = {
                                                                      request: KyRequest;
                                                                      options: NormalizedOptions;
                                                                      error: Error;
                                                                      /**
                                                                      The number of retries attempted. `0` for the initial request, increments with each retry.
                                                                      This allows you to distinguish between the initial request and retries, which is useful when you need different error handling based on retry attempts (e.g., showing different error messages on the final attempt).
                                                                      */
                                                                      retryCount: number;
                                                                      };

                                                                        type BeforeRequestHook

                                                                        type BeforeRequestHook = (
                                                                        state: BeforeRequestState
                                                                        ) => Request | Response | void | Promise<Request | Response | void>;

                                                                          type BeforeRequestState

                                                                          type BeforeRequestState = {
                                                                          request: KyRequest;
                                                                          options: NormalizedOptions;
                                                                          /**
                                                                          The number of retries attempted. Always `0`, since `beforeRequest` hooks run once before retry handling begins.
                                                                          */
                                                                          retryCount: 0;
                                                                          };

                                                                            type BeforeRetryHook

                                                                            type BeforeRetryHook = (
                                                                            state: BeforeRetryState
                                                                            ) =>
                                                                            | Request
                                                                            | Response
                                                                            | typeof stop
                                                                            | void
                                                                            | Promise<Request | Response | typeof stop | void>;

                                                                              type BeforeRetryState

                                                                              type BeforeRetryState = {
                                                                              request: KyRequest;
                                                                              options: NormalizedOptions;
                                                                              error: Error;
                                                                              /**
                                                                              The number of retries attempted. Always `>= 1`, since this hook is only called during retries, not on the initial request.
                                                                              */
                                                                              retryCount: number;
                                                                              };

                                                                                type Hooks

                                                                                type Hooks = {
                                                                                /**
                                                                                This hook enables you to modify the options before they are used to construct the request. The hook function receives the mutable options object and can modify it in place. You could, for example, modify `searchParams`, `headers`, or `json` here.
                                                                                Unlike other hooks, `init` hooks are synchronous. Any error thrown will propagate synchronously and will not be caught by `beforeError` hooks.
                                                                                A common use case is to add a search parameter to every request:
                                                                                @example
                                                                                ```
                                                                                import ky from 'ky';
                                                                                const api = ky.extend({
                                                                                hooks: {
                                                                                init: [
                                                                                options => {
                                                                                options.searchParams = {apiKey: getApiKey()};
                                                                                },
                                                                                ],
                                                                                },
                                                                                });
                                                                                const response = await api.get('https://example.com/api/users');
                                                                                // URL: https://example.com/api/users?apiKey=123
                                                                                ```
                                                                                @default []
                                                                                */
                                                                                init?: InitHook[];
                                                                                /**
                                                                                This hook enables you to modify the request right before it is sent. Ky will make no further changes to the request after this. The hook function receives a state object with the normalized request, options, and retry count. You could, for example, modify `request.headers` here.
                                                                                The `retryCount` is always `0`, since `beforeRequest` hooks run once before retry handling begins.
                                                                                The hook can return a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) to replace the outgoing request (remaining hooks will still run with the updated request). It can also return a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) to completely avoid making an HTTP request, in which case remaining `beforeRequest` hooks are skipped. This can be used to mock a request, check an internal cache, etc.
                                                                                Any error thrown by `beforeRequest` hooks is treated as fatal and will not trigger Ky's retry logic.
                                                                                @example
                                                                                ```
                                                                                import ky from 'ky';
                                                                                const api = ky.extend({
                                                                                hooks: {
                                                                                beforeRequest: [
                                                                                ({request}) => {
                                                                                request.headers.set('Authorization', 'token initial-token');
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                const response = await api.get('https://example.com/api/users');
                                                                                ```
                                                                                **Modifying the request URL:**
                                                                                @example
                                                                                ```
                                                                                import ky from 'ky';
                                                                                const api = ky.extend({
                                                                                hooks: {
                                                                                beforeRequest: [
                                                                                ({request}) => {
                                                                                const url = new URL(request.url);
                                                                                url.searchParams.set('token', 'secret-token');
                                                                                return new Request(url, request);
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                const response = await api.get('https://example.com/api/users');
                                                                                ```
                                                                                @default []
                                                                                */
                                                                                beforeRequest?: BeforeRequestHook[];
                                                                                /**
                                                                                This hook enables you to modify the request right before retry. Ky will make no further changes to the request after this. The hook function receives a state object with the normalized request, options, an error instance, and retry count. You could, for example, modify `request.headers` here.
                                                                                The hook can return a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) to replace the outgoing retry request, or return a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) to skip the retry and use that response instead. **Note:** Returning a request or response skips remaining `beforeRetry` hooks.
                                                                                **Warning:** Returned `Request` objects are used as-is. If you point one at another origin, remove any credentials you do not want forwarded.
                                                                                The `retryCount` is always `>= 1`, since this hook is only called during retries, not on the initial request.
                                                                                If the request received a response, the error will be of type `HTTPError`. The `Response` object will be available at `error.response`, and the pre-parsed response body will be available at `error.data`. Be aware that some types of errors, such as network errors, inherently mean that a response was not received. In that case, the error will be an instance of `NetworkError` instead of `HTTPError`.
                                                                                You can prevent Ky from retrying the request by throwing an error. Ky will not handle it in any way and the error will be propagated to the request initiator. The rest of the `beforeRetry` hooks will not be called in this case. Alternatively, you can return the [`ky.stop`](#kystop) symbol to do the same thing but without propagating an error (this has some limitations, see `ky.stop` docs for details).
                                                                                **Modifying headers:**
                                                                                @example
                                                                                ```
                                                                                import ky from 'ky';
                                                                                const response = await ky('https://example.com', {
                                                                                hooks: {
                                                                                beforeRetry: [
                                                                                async ({request, options, error, retryCount}) => {
                                                                                const token = await ky('https://example.com/refresh-token');
                                                                                request.headers.set('Authorization', `token ${token}`);
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                ```
                                                                                **Modifying the request URL:**
                                                                                @example
                                                                                ```
                                                                                import ky, {isHTTPError} from 'ky';
                                                                                const response = await ky('https://example.com/api', {
                                                                                hooks: {
                                                                                beforeRetry: [
                                                                                ({request, error}) => {
                                                                                // Add query parameters based on error response
                                                                                if (
                                                                                isHTTPError(error)
                                                                                && typeof error.data === 'object'
                                                                                && error.data !== null
                                                                                && 'processId' in error.data
                                                                                ) {
                                                                                const url = new URL(request.url);
                                                                                url.searchParams.set('processId', String(error.data.processId));
                                                                                return new Request(url, request);
                                                                                }
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                ```
                                                                                **Returning a cached response:**
                                                                                @example
                                                                                ```
                                                                                import ky from 'ky';
                                                                                const response = await ky('https://example.com/api', {
                                                                                hooks: {
                                                                                beforeRetry: [
                                                                                ({error, retryCount}) => {
                                                                                // Use cached response instead of retrying
                                                                                if (retryCount > 1 && cachedResponse) {
                                                                                return cachedResponse;
                                                                                }
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                ```
                                                                                @default []
                                                                                */
                                                                                beforeRetry?: BeforeRetryHook[];
                                                                                /**
                                                                                This hook enables you to modify any error right before it is thrown. The hook function receives a state object with the current request, the normalized Ky options, the error, and retry count, and should return an `Error` instance.
                                                                                This hook is called for all error types, including `HTTPError`, `NetworkError`, `TimeoutError`, and `ForceRetryError` (when retry limit is exceeded via `ky.retry()`). Use type guards like `isHTTPError()`, `isNetworkError()`, or `isTimeoutError()` to handle specific error types.
                                                                                The `retryCount` is `0` for the initial request and increments with each retry. This allows you to distinguish between the initial request and retries, which is useful when you need different error handling based on retry attempts (e.g., showing different error messages on the final attempt).
                                                                                If a `beforeRequest` or `beforeRetry` hook returns a new `Request`, inspect `request` for the final request state. `options` remains Ky's normalized options and may not mirror every property of a replacement `Request`.
                                                                                @default []
                                                                                @example
                                                                                ```
                                                                                import ky, {isHTTPError} from 'ky';
                                                                                await ky('https://example.com', {
                                                                                hooks: {
                                                                                beforeError: [
                                                                                ({request, options, error}) => {
                                                                                if (isHTTPError(error)) {
                                                                                if (
                                                                                typeof error.data === 'object'
                                                                                && error.data !== null
                                                                                && 'message' in error.data
                                                                                ) {
                                                                                error.name = 'GitHubError';
                                                                                error.message = `${String(error.data.message)} (${error.response.status})`;
                                                                                }
                                                                                }
                                                                                // `request` and `options` are always available
                                                                                console.log(`Request to ${request.url} failed`, options.context);
                                                                                return error;
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                ```
                                                                                */
                                                                                beforeError?: BeforeErrorHook[];
                                                                                /**
                                                                                This hook enables you to read and optionally modify the response. The hook function receives a state object with the normalized request, options, a clone of the response, and retry count. The return value of the hook function will be used by Ky as the response object if it's an instance of [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
                                                                                You can also force a retry by returning [`ky.retry(options)`](#kyretryoptions). This is useful when you need to retry based on the response body content, even if the response has a successful status code. The retry will respect the `retry.limit` option and be observable in `beforeRetry` hooks.
                                                                                **Warning:** `ky.retry({request})` uses the replacement request as-is. If it targets another origin, remove any credentials you do not want forwarded.
                                                                                Any non-`ky.retry()` error thrown by `afterResponse` hooks is treated as fatal and will not trigger Ky's retry logic.
                                                                                The `retryCount` is `0` for the initial request and increments with each retry. This allows you to distinguish between the initial request and retries, which is useful when you need different behavior for retries (e.g., showing a notification only on the final retry).
                                                                                @default []
                                                                                @example
                                                                                ```
                                                                                import ky from 'ky';
                                                                                const response = await ky('https://example.com', {
                                                                                hooks: {
                                                                                afterResponse: [
                                                                                ({response}) => {
                                                                                // You could do something with the response, for example, logging.
                                                                                log(response);
                                                                                // Or return a `Response` instance to overwrite the response.
                                                                                return new Response('A different response', {status: 200});
                                                                                },
                                                                                // Or retry with a fresh token on a 401 error
                                                                                async ({request, response, retryCount}) => {
                                                                                if (response.status === 401 && retryCount === 0) {
                                                                                // Only refresh on first 401, not on subsequent retries
                                                                                const {token} = await ky.post('https://example.com/auth/refresh').json();
                                                                                const headers = new Headers(request.headers);
                                                                                headers.set('Authorization', `Bearer ${token}`);
                                                                                return ky.retry({
                                                                                request: new Request(request, {headers}),
                                                                                code: 'TOKEN_REFRESHED'
                                                                                });
                                                                                }
                                                                                },
                                                                                // Or force retry based on response body content
                                                                                async ({response}) => {
                                                                                if (response.status === 200) {
                                                                                const data = await response.json();
                                                                                if (data.error?.code === 'RATE_LIMIT') {
                                                                                // Retry with custom delay from API response
                                                                                return ky.retry({
                                                                                delay: data.error.retryAfter * 1000,
                                                                                code: 'RATE_LIMIT'
                                                                                });
                                                                                }
                                                                                }
                                                                                },
                                                                                // Or show a notification only on the last retry for 5xx errors
                                                                                ({options, response, retryCount}) => {
                                                                                if (response.status >= 500 && response.status <= 599) {
                                                                                if (retryCount === options.retry.limit) {
                                                                                showNotification('Request failed after all retries');
                                                                                }
                                                                                }
                                                                                }
                                                                                ]
                                                                                }
                                                                                });
                                                                                ```
                                                                                */
                                                                                afterResponse?: AfterResponseHook[];
                                                                                };

                                                                                  type InitHook

                                                                                  type InitHook = (options: Options) => void;
                                                                                  • This hook enables you to modify the options before they are used to construct the request. The hook function receives the mutable options object and can modify it in place. You could, for example, modify searchParams, headers, or json here.

                                                                                    Unlike other hooks, init hooks are synchronous. Any error thrown will propagate synchronously and will not be caught by beforeError hooks.

                                                                                    Example 1

                                                                                    import ky from 'ky';
                                                                                    const api = ky.extend({
                                                                                    hooks: {
                                                                                    init: [
                                                                                    options => {
                                                                                    options.searchParams = {apiKey: getApiKey()};
                                                                                    },
                                                                                    ],
                                                                                    },
                                                                                    });
                                                                                    const response = await api.get('https://example.com/api/users');
                                                                                    // URL: https://example.com/api/users?apiKey=123

                                                                                  type Input

                                                                                  type Input = string | URL | Request;

                                                                                    type KyInstance

                                                                                    type KyInstance = {
                                                                                    /**
                                                                                    Fetch the given `url`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` method added.
                                                                                    @example
                                                                                    ```
                                                                                    import ky from 'ky';
                                                                                    const json = await ky('https://example.com', {json: {foo: true}}).json();
                                                                                    console.log(json);
                                                                                    //=> `{data: '🦄'}`
                                                                                    ```
                                                                                    */
                                                                                    <T>(url: Input, options?: Options): ResponsePromise<T>;
                                                                                    /**
                                                                                    Fetch the given `url` using the option `{method: 'get'}`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` methods added.
                                                                                    */
                                                                                    get: <T>(url: Input, options?: Options) => ResponsePromise<T>;
                                                                                    /**
                                                                                    Fetch the given `url` using the option `{method: 'post'}`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` methods added.
                                                                                    */
                                                                                    post: <T>(url: Input, options?: Options) => ResponsePromise<T>;
                                                                                    /**
                                                                                    Fetch the given `url` using the option `{method: 'put'}`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` methods added.
                                                                                    */
                                                                                    put: <T>(url: Input, options?: Options) => ResponsePromise<T>;
                                                                                    /**
                                                                                    Fetch the given `url` using the option `{method: 'delete'}`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` methods added.
                                                                                    */
                                                                                    delete: <T>(url: Input, options?: Options) => ResponsePromise<T>;
                                                                                    /**
                                                                                    Fetch the given `url` using the option `{method: 'patch'}`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` methods added.
                                                                                    */
                                                                                    patch: <T>(url: Input, options?: Options) => ResponsePromise<T>;
                                                                                    /**
                                                                                    Fetch the given `url` using the option `{method: 'head'}`.
                                                                                    @param url - `Request` object, `URL` object, or URL string.
                                                                                    @returns A promise with `Body` methods added.
                                                                                    */
                                                                                    head: (url: Input, options?: Options) => ResponsePromise;
                                                                                    /**
                                                                                    Create a new Ky instance with complete new defaults, without inheriting from any parent instance.
                                                                                    @returns A new Ky instance.
                                                                                    */
                                                                                    create: (defaultOptions?: Options) => KyInstance;
                                                                                    /**
                                                                                    Create a new Ky instance with some defaults overridden with your own.
                                                                                    In contrast to `ky.create()`, `ky.extend()` inherits defaults from its parent.
                                                                                    You can pass headers as a `Headers` instance or a plain object.
                                                                                    You can remove a header with `.extend()` by passing the header with an `undefined` value. Passing `undefined` as a string removes the header only if it comes from a `Headers` instance.
                                                                                    Similarly, you can remove existing `hooks` entries by extending the hook with an explicit `undefined`.
                                                                                    By default, `.extend()` deep-merges options: hooks are appended, headers are merged, and search parameters are accumulated. Use `replaceOption` when you want to fully replace a merged property instead.
                                                                                    You can also refer to parent defaults by providing a function to `.extend()`.
                                                                                    @example
                                                                                    ```
                                                                                    import ky from 'ky';
                                                                                    const api = ky.create({prefix: 'https://example.com/api'});
                                                                                    const usersApi = api.extend((options) => ({prefix: `${options.prefix}/users`}));
                                                                                    const response = await usersApi.get('123');
                                                                                    //=> 'https://example.com/api/users/123'
                                                                                    const response = await api.get('version');
                                                                                    //=> 'https://example.com/api/version'
                                                                                    ```
                                                                                    @returns A new Ky instance.
                                                                                    */
                                                                                    extend: (
                                                                                    defaultOptions: Options | ((parentOptions: Options) => Options)
                                                                                    ) => KyInstance;
                                                                                    /**
                                                                                    A `Symbol` that can be returned by a `beforeRetry` hook to stop the retry. This will also short circuit the remaining `beforeRetry` hooks.
                                                                                    Note: Returning this symbol makes Ky abort and return with an `undefined` response. Be sure to check for a response before accessing any properties on it or use [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining). It is also incompatible with body methods, such as `.json()` or `.text()`, because there is no response to parse. In general, we recommend throwing an error instead of returning this symbol, as that will cause Ky to abort and then throw, which avoids these limitations.
                                                                                    A valid use-case for `ky.stop` is to prevent retries when making requests for side effects, where the returned data is not important. For example, logging client activity to the server.
                                                                                    @example
                                                                                    ```
                                                                                    import ky from 'ky';
                                                                                    const options = {
                                                                                    hooks: {
                                                                                    beforeRetry: [
                                                                                    async ({request, options, error, retryCount}) => {
                                                                                    const shouldStopRetry = await ky('https://example.com/api');
                                                                                    if (shouldStopRetry) {
                                                                                    return ky.stop;
                                                                                    }
                                                                                    }
                                                                                    ]
                                                                                    }
                                                                                    };
                                                                                    // Note that response will be `undefined` in case `ky.stop` is returned.
                                                                                    const response = await ky.post('https://example.com', options);
                                                                                    // Using `.text()` or other body methods is not supported.
                                                                                    const text = await ky('https://example.com', options).text();
                                                                                    ```
                                                                                    */
                                                                                    readonly stop: typeof stop;
                                                                                    /**
                                                                                    Force a retry from an `afterResponse` hook.
                                                                                    This allows you to retry a request based on the response content, even if the response has a successful status code. The retry will respect the `retry.limit` option and skip the `shouldRetry` check. The forced retry is observable in `beforeRetry` hooks, where the error will be a `ForceRetryError`.
                                                                                    @example
                                                                                    ```
                                                                                    import ky, {isForceRetryError} from 'ky';
                                                                                    const api = ky.extend({
                                                                                    hooks: {
                                                                                    afterResponse: [
                                                                                    async ({response}) => {
                                                                                    // Retry based on response body content
                                                                                    if (response.status === 200) {
                                                                                    const data = await response.json();
                                                                                    // Simple retry with default delay
                                                                                    if (data.error?.code === 'TEMPORARY_ERROR') {
                                                                                    return ky.retry();
                                                                                    }
                                                                                    // Retry with custom delay from API response
                                                                                    if (data.error?.code === 'RATE_LIMIT') {
                                                                                    return ky.retry({
                                                                                    delay: data.error.retryAfter * 1000,
                                                                                    code: 'RATE_LIMIT'
                                                                                    });
                                                                                    }
                                                                                    }
                                                                                    }
                                                                                    ],
                                                                                    beforeRetry: [
                                                                                    ({error, retryCount}) => {
                                                                                    // Observable in beforeRetry hooks
                                                                                    if (isForceRetryError(error)) {
                                                                                    console.log(`Forced retry #${retryCount}: ${error.message}`);
                                                                                    // Example output: "Forced retry #1: Forced retry: RATE_LIMIT"
                                                                                    }
                                                                                    }
                                                                                    ]
                                                                                    }
                                                                                    });
                                                                                    const response = await api.get('https://example.com/api');
                                                                                    ```
                                                                                    */
                                                                                    readonly retry: typeof retry;
                                                                                    };

                                                                                      type KyRequest

                                                                                      type KyRequest<T = unknown> = {
                                                                                      json: <J = T>() => Promise<J>;
                                                                                      } & Request;

                                                                                        type KyResponse

                                                                                        type KyResponse<T = unknown> = {
                                                                                        json: <J = T>() => Promise<J>;
                                                                                        } & Response;

                                                                                          type Progress

                                                                                          type Progress = {
                                                                                          /**
                                                                                          A number between `0` and `1` representing the progress percentage.
                                                                                          */
                                                                                          percent: number;
                                                                                          /**
                                                                                          The number of bytes transferred so far.
                                                                                          */
                                                                                          transferredBytes: number;
                                                                                          /**
                                                                                          The total number of bytes to be transferred. This is an estimate and may be `0` if the total size cannot be determined.
                                                                                          */
                                                                                          totalBytes: number;
                                                                                          };

                                                                                            type ResponsePromise

                                                                                            type ResponsePromise<T = unknown> = {
                                                                                            arrayBuffer: () => Promise<ArrayBuffer>;
                                                                                            blob: () => Promise<Blob>;
                                                                                            formData: () => Promise<FormData>;
                                                                                            /**
                                                                                            Get the response body as raw bytes.
                                                                                            Note: This shortcut is only available when the runtime supports `Response.prototype.bytes()`.
                                                                                            */
                                                                                            bytes: () => Promise<Uint8Array>;
                                                                                            json: {
                                                                                            /**
                                                                                            Get the response body as JSON.
                                                                                            @example
                                                                                            ```
                                                                                            import ky from 'ky';
                                                                                            const json = await ky(…).json();
                                                                                            ```
                                                                                            @example
                                                                                            ```
                                                                                            import ky from 'ky';
                                                                                            interface Result {
                                                                                            value: number;
                                                                                            }
                                                                                            const result1 = await ky(…).json<Result>();
                                                                                            // or
                                                                                            const result2 = await ky<Result>(…).json();
                                                                                            ```
                                                                                            */
                                                                                            <JsonType = T>(): Promise<JsonType>;
                                                                                            /**
                                                                                            Get the response body as JSON and validate it with a Standard Schema.
                                                                                            Use a Standard Schema compatible validator (for example, Zod 3.24+).
                                                                                            Throws a `SchemaValidationError` when validation fails.
                                                                                            @example
                                                                                            ```
                                                                                            import ky from 'ky';
                                                                                            import {z} from 'zod';
                                                                                            const userSchema = z.object({name: z.string()});
                                                                                            const user = await ky('/api/user').json(userSchema);
                                                                                            ```
                                                                                            */
                                                                                            <Schema extends StandardSchemaV1>(schema: Schema): Promise<
                                                                                            StandardSchemaV1InferOutput<Schema>
                                                                                            >;
                                                                                            };
                                                                                            text: () => Promise<string>;
                                                                                            } & Promise<KyResponse<T>>;

                                                                                              type RetryOptions

                                                                                              type RetryOptions = {
                                                                                              /**
                                                                                              The number of times to retry failed requests.
                                                                                              @default 2
                                                                                              */
                                                                                              limit?: number;
                                                                                              /**
                                                                                              The HTTP methods allowed to retry.
                                                                                              @default ['get', 'put', 'head', 'delete', 'options', 'trace']
                                                                                              */
                                                                                              methods?: HttpMethod[];
                                                                                              /**
                                                                                              The HTTP status codes allowed to retry.
                                                                                              @default [408, 413, 429, 500, 502, 503, 504]
                                                                                              */
                                                                                              statusCodes?: number[];
                                                                                              /**
                                                                                              The HTTP status codes allowed to retry with a `Retry-After` header.
                                                                                              @default [413, 429, 503]
                                                                                              */
                                                                                              afterStatusCodes?: number[];
                                                                                              /**
                                                                                              If the `Retry-After` header is greater than `maxRetryAfter`, it will use `maxRetryAfter`.
                                                                                              @default Infinity
                                                                                              */
                                                                                              maxRetryAfter?: number;
                                                                                              /**
                                                                                              The upper limit of the delay per retry in milliseconds.
                                                                                              To clamp the delay, set `backoffLimit` to 1000, for example.
                                                                                              By default, the delay is calculated in the following way:
                                                                                              ```
                                                                                              0.3 * (2 ** (attemptCount - 1)) * 1000
                                                                                              ```
                                                                                              The delay increases exponentially.
                                                                                              @default Infinity
                                                                                              */
                                                                                              backoffLimit?: number;
                                                                                              /**
                                                                                              A function to calculate the delay in milliseconds between retries given `attemptCount` (starts from 1).
                                                                                              @default attemptCount => 0.3 * (2 ** (attemptCount - 1)) * 1000
                                                                                              */
                                                                                              delay?: (attemptCount: number) => number;
                                                                                              /**
                                                                                              Add random jitter to retry delays to prevent thundering herd problems.
                                                                                              When many clients retry simultaneously (e.g., after hitting a rate limit), they can overwhelm the server again. Jitter adds randomness to break this synchronization.
                                                                                              Set to `true` to use full jitter, which randomizes the delay between 0 and the computed delay.
                                                                                              Alternatively, pass a function to implement custom jitter strategies.
                                                                                              Note: Jitter is not applied when the server provides a `Retry-After` header, as the server's explicit timing should be respected.
                                                                                              @default undefined (no jitter)
                                                                                              @example
                                                                                              ```
                                                                                              import ky from 'ky';
                                                                                              const json = await ky('https://example.com', {
                                                                                              retry: {
                                                                                              limit: 5,
                                                                                              // Full jitter (randomizes delay between 0 and computed value)
                                                                                              jitter: true
                                                                                              // Percentage jitter (80-120% of delay)
                                                                                              // jitter: delay => delay * (0.8 + Math.random() * 0.4)
                                                                                              // Absolute jitter (±100ms)
                                                                                              // jitter: delay => delay + (Math.random() * 200 - 100)
                                                                                              }
                                                                                              }).json();
                                                                                              ```
                                                                                              */
                                                                                              jitter?: boolean | ((delay: number) => number) | undefined;
                                                                                              /**
                                                                                              Whether to retry when the request times out.
                                                                                              @default false
                                                                                              @example
                                                                                              ```
                                                                                              import ky from 'ky';
                                                                                              const json = await ky('https://example.com', {
                                                                                              retry: {
                                                                                              limit: 3,
                                                                                              retryOnTimeout: true
                                                                                              }
                                                                                              }).json();
                                                                                              ```
                                                                                              */
                                                                                              retryOnTimeout?: boolean;
                                                                                              /**
                                                                                              A function to determine whether a retry should be attempted.
                                                                                              This function takes precedence over the default retry checks (`retryOnTimeout`, status code checks, etc.) for retriable methods. It is only called after the retry limit and method checks pass.
                                                                                              **Note:** This is different from the `beforeRetry` hook:
                                                                                              - `shouldRetry`: Controls WHETHER to retry (called before the retry decision is made)
                                                                                              - `beforeRetry`: Called AFTER retry is confirmed, allowing you to modify the request
                                                                                              Should return:
                                                                                              - `true` to force a retry (bypasses `retryOnTimeout`, status code checks, and other validations)
                                                                                              - `false` to prevent a retry (no retry will occur)
                                                                                              - `undefined` to use the default retry logic (`retryOnTimeout`, status codes, network errors). Unrecognized error types are not retried.
                                                                                              @default undefined
                                                                                              @example
                                                                                              ```
                                                                                              import ky, {HTTPError} from 'ky';
                                                                                              const json = await ky('https://example.com', {
                                                                                              retry: {
                                                                                              limit: 3,
                                                                                              shouldRetry: ({error, retryCount}) => {
                                                                                              // Retry on specific business logic errors from API
                                                                                              if (error instanceof HTTPError) {
                                                                                              const status = error.response.status;
                                                                                              // Retry on 429 (rate limit) but only for first 2 attempts
                                                                                              if (status === 429 && retryCount <= 2) {
                                                                                              return true;
                                                                                              }
                                                                                              // Don't retry on 4xx errors except rate limits
                                                                                              if (status >= 400 && status < 500) {
                                                                                              return false;
                                                                                              }
                                                                                              }
                                                                                              // Use default retry logic for other errors
                                                                                              return undefined;
                                                                                              }
                                                                                              }
                                                                                              }).json();
                                                                                              ```
                                                                                              */
                                                                                              shouldRetry?: (
                                                                                              state: ShouldRetryState
                                                                                              ) => boolean | undefined | Promise<boolean | undefined>;
                                                                                              };

                                                                                                type SearchParamsOption

                                                                                                type SearchParamsOption =
                                                                                                | SearchParamsInit
                                                                                                | Record<string, string | number | boolean | undefined>
                                                                                                | Array<Array<string | number | boolean>>;

                                                                                                  type ShouldRetryState

                                                                                                  type ShouldRetryState = {
                                                                                                  /**
                                                                                                  The error that caused the request to fail.
                                                                                                  */
                                                                                                  error: Error;
                                                                                                  /**
                                                                                                  The number of retries attempted. Starts at 1 for the first retry.
                                                                                                  */
                                                                                                  retryCount: number;
                                                                                                  };

                                                                                                    type StandardSchemaV1

                                                                                                    type StandardSchemaV1<InputType = unknown, OutputType = InputType> = {
                                                                                                    readonly '~standard': {
                                                                                                    readonly version: 1;
                                                                                                    readonly vendor: string;
                                                                                                    readonly validate: (
                                                                                                    value: unknown,
                                                                                                    options?: StandardSchemaV1Options
                                                                                                    ) =>
                                                                                                    | StandardSchemaV1Result<OutputType>
                                                                                                    | Promise<StandardSchemaV1Result<OutputType>>;
                                                                                                    readonly types?: StandardSchemaV1Types<InputType, OutputType> | undefined;
                                                                                                    };
                                                                                                    };

                                                                                                      type StandardSchemaV1InferOutput

                                                                                                      type StandardSchemaV1InferOutput<Schema extends StandardSchemaV1> =
                                                                                                      Schema['~standard'] extends {
                                                                                                      readonly types: StandardSchemaV1Types<unknown, infer OutputType>;
                                                                                                      }
                                                                                                      ? OutputType
                                                                                                      : Extract<
                                                                                                      Awaited<ReturnType<Schema['~standard']['validate']>>,
                                                                                                      StandardSchemaV1SuccessResult<unknown>
                                                                                                      > extends StandardSchemaV1SuccessResult<infer OutputType>
                                                                                                      ? OutputType
                                                                                                      : unknown;

                                                                                                        type StandardSchemaV1Issue

                                                                                                        type StandardSchemaV1Issue = {
                                                                                                        readonly message: string;
                                                                                                        readonly path?:
                                                                                                        | ReadonlyArray<
                                                                                                        | PropertyKey
                                                                                                        | {
                                                                                                        readonly key: PropertyKey;
                                                                                                        }
                                                                                                        >
                                                                                                        | undefined;
                                                                                                        };

                                                                                                          Package Files (17)

                                                                                                          Dependencies (0)

                                                                                                          No dependencies.

                                                                                                          Dev Dependencies (15)

                                                                                                          Peer Dependencies (0)

                                                                                                          No peer dependencies.

                                                                                                          Badge

                                                                                                          To add a badge like this onejsDocs.io badgeto your package's README, use the codes available below.

                                                                                                          You may also use Shields.io to create a custom badge linking to https://www.jsdocs.io/package/ky.

                                                                                                          • Markdown
                                                                                                            [![jsDocs.io](https://img.shields.io/badge/jsDocs.io-reference-blue)](https://www.jsdocs.io/package/ky)
                                                                                                          • HTML
                                                                                                            <a href="https://www.jsdocs.io/package/ky"><img src="https://img.shields.io/badge/jsDocs.io-reference-blue" alt="jsDocs.io"></a>