[> Back to homepage](../readme.md#documentation)
## Options
Source code: [`source/core/options.ts`](../source/core/options.ts)
Like `fetch` stores the options in a `Request` instance, Got does so in `Options`.\
It is made of getters and setters that provide fast option normalization and validation.
**By default, Got will retry on failure. To disable this option, set [`options.retry`](7-retry.md) to `{limit: 0}`.**
#### Merge behavior explained
When an option is already set, setting it again replaces it with a deep clone by default.\
Otherwise the merge behavior is documented in the corresponding section for the option.
#### How to store options
The `Options` class is useful for storing and validating configuration for Got instances.
The constructor - `new Options(url, options, defaults)` - takes the same arguments as the `got` function.
To use an `Options` instance, create an extended Got instance:
```js
import got, {Options} from 'got';
const options = new Options({
prefixUrl: 'https://httpbin.org',
headers: {
foo: 'foo'
}
});
options.headers.foo = 'bar';
// Use got.extend() to create an instance with the Options
const instance = got.extend(options);
const {headers} = await instance('anything').json();
console.log(headers.foo);
//=> 'bar'
```
For most use cases, plain objects are simpler and more convenient:
```js
import got from 'got';
const options = {
prefixUrl: 'https://httpbin.org',
headers: {
foo: 'foo'
}
};
options.headers.foo = 'bar';
// Plain objects can be passed directly as the second argument
const {headers} = await got('anything', options).json();
console.log(headers.foo);
//=> 'bar'
```
Note that the `Options` constructor throws immediately when an invalid option is provided, such as a non-existing option or a typo. With plain objects, validation only happens when the request is made.
For TypeScript users, `got` exports a dedicated type called `OptionsInit`.\
It is a plain object that can store the same properties as `Options`.
The `Options` class is useful for storing the base configuration of a custom Got client, especially when you want early validation of options.
#### Resetting options
Unlike Got 11, explicitly specifying `undefined` no longer keeps the parent value.\
In order to keep the parent value, you must not set an option to `undefined`.\
Doing so will reset those values:
```js
instance(…, {searchParams: undefined});
instance(…, {cookieJar: undefined});
instance(…, {responseType: undefined});
instance(…, {prefixUrl: ''});
instance(…, {agent: {http: undefined, https: undefined, http2: undefined}});
instance(…, {context: {token: undefined, …}});
instance(…, {https: {rejectUnauthorized: undefined, …}});
instance(…, {cacheOptions: {immutableMinTimeToLive: undefined, …}});
instance(…, {headers: {'user-agent': undefined, …}});
instance(…, {timeout: {request: undefined, …}});
```
In order to reset `hooks`, `retry` and `pagination`, another Got instance must be created:
```js
const defaults = new Options();
const secondInstance = instance.extend({mutableDefaults: true});
secondInstance.defaults.options.hooks = defaults.hooks;
secondInstance.defaults.options.retry = defaults.retry;
secondInstance.defaults.options.pagination = defaults.pagination;
```
### `url`
**Type: string | [URL](https://nodejs.org/api/url.html#url_the_whatwg_url_api)**
The URL to request. Usually the `url` represents a [WHATWG URL](https://url.spec.whatwg.org/#url-class).
Pass it as the first argument to `got(url, options)`. Passing `url` in an options object is not supported.
```js
import got from 'got';
// This:
await got('https://httpbin.org/anything');
// is semantically the same as this:
await got(new URL('https://httpbin.org/anything'));
```
> [!NOTE]
> Throws if no protocol specified.
> [!NOTE]
> If `url` is a string, then the `query` string will **not** be parsed as search params.\
> This is in accordance to [the specification](https://datatracker.ietf.org/doc/html/rfc7230#section-2.7).\
> If you want to pass search params instead, use the `searchParams` option below.
```js
import got from 'got';
await got('https://httpbin.org/anything?query=a b'); //=> ?query=a%20b
await got('https://httpbin.org/anything', {searchParams: {query: 'a b'}}); //=> ?query=a+b
// The query string is overridden by `searchParams`
await got('https://httpbin.org/anything?query=a b', {searchParams: {query: 'a b'}}); //=> ?query=a+b
```
> [!NOTE]
> Leading slashes are disallowed to enforce consistency and avoid confusion.\
> For example, when the prefix URL is `https://example.com/foo` and the input is `/bar`, there's ambiguity whether the resulting URL would become `https://example.com/foo/bar` or `https://example.com/bar`. The latter is used by browsers.
### `searchParams`
**Type: string | [URLSearchParams](https://nodejs.org/api/url.html#url_class_urlsearchparams) | object<string, [Primitive](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html)>**
[WHATWG URL Search Params](https://url.spec.whatwg.org/#interface-urlsearchparams) to be added to the request URL.
```js
import got from 'got';
const response = await got('https://httpbin.org/anything', {
searchParams: {
hello: 'world',
foo: 123
}
}).json();
console.log(response.args);
//=> {hello: 'world', foo: 123}
```
If you need to pass an array, you can do it using a `URLSearchParams` instance:
```js
import got from 'got';
const searchParams = new URLSearchParams([['key', 'a'], ['key', 'b']]);
await got('https://httpbin.org/anything', {searchParams});
console.log(searchParams.toString());
//=> 'key=a&key=b'
```
> [!NOTE]
> This will override the `query` string in `url`.
> [!NOTE]
> - `null` values are not stringified, an empty string is used instead.
> - `undefined` values will clear the original keys.
#### **Merge behavior:**
> - Overrides existing properties.
### `prefixUrl`
**Type: `string`**\
**Default: `''`**
The string to be prepended to relative string `url` input.
The prefix can be any valid URL, either relative or [absolute](https://url.spec.whatwg.org/#absolute-url-string).
A trailing slash `/` is optional - one will be added automatically.
```js
import got from 'got';
// This:
const instance = got.extend({prefixUrl: 'https://httpbin.org'});
await instance('anything');
// is semantically the same as this:
await got('https://httpbin.org/anything');
```
> [!NOTE]
> Changing `prefixUrl` also updates the `url` option if set.
> [!NOTE]
> Absolute string URLs and `URL` instances bypass `prefixUrl` by default. Other instance defaults, including `headers`, still apply. If those URLs may come from untrusted input, set [`allowAbsoluteUrls`](#allowabsoluteurls) to `false`.
> [!NOTE]
> Got cannot know which custom headers are sensitive. If you use headers like `x-api-key`, only pass trusted URLs or use `allowAbsoluteUrls: false`.
### `allowAbsoluteUrls`
**Type: `boolean`**\
**Default: `true`**
Allow absolute URLs to bypass `prefixUrl`.
When set to `false` with `prefixUrl`, passing an absolute URL will throw. This also rejects scheme-relative URL strings like `//example.com/path` in retry and pagination URL overrides. Use this when untrusted URL input must stay on the same origin as the configured `prefixUrl`. This is not a path sandbox: relative paths like `../other` still follow standard URL resolution on the same origin.
```js
import got from 'got';
const client = got.extend({
prefixUrl: 'https://api.example.com',
allowAbsoluteUrls: false,
headers: {
'x-api-key': process.env.API_KEY
}
});
await client('users/1');
// Requests https://api.example.com/users/1
await client('https://attacker.example');
// Throws
```
Set `prefixUrl` to an empty string for a request that intentionally needs an absolute URL:
```js
await client('https://trusted.example', {prefixUrl: ''});
```
> [!NOTE]
> This guards the `url` you pass. It does not block cross-origin redirects issued by the server, though inherited sensitive headers are still stripped when a redirect changes origin.
> [!NOTE]
> The check is defeated if the same hook or `pagination.paginate(…)` return also sets `prefixUrl` or `allowAbsoluteUrls`. Do not populate those options from untrusted data.
### `signal`
**Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)**
You can abort the `request` using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
```js
import got from 'got';
const abortController = new AbortController();
const request = got('https://httpbin.org/anything', {
signal: abortController.signal
});
setTimeout(() => {
abortController.abort();
}, 100);
```
### `method`
**Type: `string`**\
**Default: `GET`**
The [HTTP method](https://httpwg.org/specs/rfc9110.html#methods) used to make the request.\
Common methods include: `GET`, `HEAD`, `POST`, `PUT`, `DELETE`.
Got also supports `QUERY`, which is defined in [RFC 10008](https://www.rfc-editor.org/rfc/rfc10008.html).
```js
import got from 'got';
const {method} = await got('https://httpbin.org/anything', {
method: 'POST'
}).json();
console.log(method);
// => 'POST'
```
### `headers`
**Type: `object`**\
**Default: `{}`**
The [HTTP headers](https://datatracker.ietf.org/doc/html/rfc7231#section-8.3) to be sent. Headers set to `undefined` will be omitted.
```js
import got from 'got';
const {headers} = await got.post('https://httpbin.org/anything', {
headers: {
hello: 'world'
}
}).json();
console.log(headers);
// => {hello: 'world'}
```
#### **Merge behavior:**
> - Overrides existing properties.
### `body`
**Type: `string | Uint8Array | TypedArray | stream.Readable | Generator | AsyncGenerator | Iterable | AsyncIterable | FormData`**
The payload to send.
For `string`, `Uint8Array`, and `TypedArray` types, the `content-length` header is automatically set if the `content-length` and `transfer-encoding` headers are missing.
**The `content-length` header is not automatically set when `body` is an instance of [`fs.createReadStream()`](https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options).**
To set `content-length` for file streams, you need to manually provide it using `fs.promises.stat()`:
```js
import fs from 'node:fs';
import fsPromises from 'node:fs/promises';
import got from 'got';
const filePath = 'path/to/file';
const fileStats = await fsPromises.stat(filePath);
const fileStream = fs.createReadStream(filePath);
await got.post('https://httpbin.org/anything', {
body: fileStream,
headers: {
'content-length': fileStats.size.toString()
}
});
```
```js
import got from 'got';
const {data} = await got.post('https://httpbin.org/anything', {
body: 'Hello, world!'
}).json();
console.log(data);
//=> 'Hello, world!'
```
You can also use typed arrays (Uint8Array, Uint16Array, etc.) as request body:
```js
import got from 'got';
const uint8Body = new Uint8Array([104, 101, 108, 108, 111]); // 'hello' in ASCII
const {data} = await got.post('https://httpbin.org/anything', {
body: uint8Body
}).json();
console.log(data);
//=> 'hello'
```
You can use `Iterable` and `AsyncIterable` objects as request body, including Web [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream):
```js
import got from 'got';
// Using an async generator
async function* generateData() {
yield 'Hello, ';
yield 'world!';
}
await got.post('https://httpbin.org/anything', {
body: generateData()
});
```
You can use [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) objects as request body:
```js
import got from 'got';
const form = new FormData();
form.set('greeting', 'Hello, world!');
const data = await got.post('https://httpbin.org/post', {
body: form
}).json();
console.log(data.form.greeting);
//=> 'Hello, world!'
```
> [!NOTE]
> If `body` is specified, then the `json` or `form` option cannot be used.
> [!NOTE]
> If you use this option, `got.stream()` will be read-only.
> [!NOTE]
> Passing `body` with `GET` will throw unless the [`allowGetBody` option](#allowgetbody) is set to `true`.
> [!NOTE]
> This option is not enumerable and will not be merged with the instance defaults.
### `json`
**Type: JSON-serializable values**
JSON **request** body. If set, the `content-type` header defaults to `application/json`.
> [!IMPORTANT]
> This option only affects the **request body** you send to the server. To parse the **response** as JSON, you must either call `.json()` on the promise or set [`responseType: 'json'`](#responsetype) in the options.
```js
import got from 'got';
const {data} = await got.post('https://httpbin.org/anything', {
json: {
hello: 'world'
}
}).json();
console.log(data);
//=> `{hello: 'world'}`
```
### `form`
**Type: object<string, [Primitive](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html)>**
The form body is converted to a query string using `(new URLSearchParams(form)).toString()`.
If set, the `content-type` header defaults to [`application/x-www-form-urlencoded`](https://url.spec.whatwg.org/#application/x-www-form-urlencoded).
```js
import got from 'got';
const {data} = await got.post('https://httpbin.org/anything', {
form: {
hello: 'world'
}
}).json();
console.log(data);
//=> 'hello=world'
```
### `parseJson`
**Type: `(text: string) => unknown`**\
**Default: `(text: string) => JSON.parse(text)`**
The function used to parse JSON responses.
```js
import got from 'got';
import Bourne from '@hapi/bourne';
// Preventing prototype pollution by using Bourne
const parsed = await got('https://example.com', {
parseJson: text => Bourne.parse(text)
}).json();
console.log(parsed);
```
### `stringifyJson`
**Type: `(object: unknown) => string`**\
**Default: `(object: unknown) => JSON.stringify(object)`**
The function used to stringify the body of JSON requests.
**Example: ignore all properties starting with an underscore**
```js
import got from 'got';
await got.post('https://example.com', {
stringifyJson: object => JSON.stringify(object, (key, value) => {
if (key.startsWith('_')) {
return;
}
return value;
}),
json: {
some: 'payload',
_ignoreMe: 1234
}
});
```
**Example: all numbers as strings**
```js
import got from 'got';
await got.post('https://example.com', {
stringifyJson: object => JSON.stringify(object, (key, value) => {
if (typeof value === 'number') {
return value.toString();
}
return value;
}),
json: {
some: 'payload',
number: 1
}
});
```
### `allowGetBody`
**Type: `boolean`**\
**Default: `false`**
Set this to `true` to allow sending body for the `GET` method.
> [!NOTE]
> This option is only meant to interact with non-compliant servers when you have no other choice.
> [!NOTE]
> The [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.1) doesn't specify any particular behavior for the GET method having a payload, therefore it's considered an [**anti-pattern**](https://en.wikipedia.org/wiki/Anti-pattern).
### `copyPipedHeaders`
**Type: `boolean`**\
**Default: `false`**
Automatically copy headers from piped streams.
When piping a request into a Got stream (e.g., `request.pipe(got.stream(url))`), this controls whether headers from the source stream are automatically merged into the Got request headers.
**Note:** Explicitly set headers take precedence over piped headers. Piped headers are only copied when a header is not already explicitly set.
Useful for proxy scenarios when explicitly enabled. Got automatically omits `host`, hop-by-hop headers, and headers nominated by `Connection`, but you may still want to filter out app-specific sensitive headers like `Authorization`, `Cookie`, etc.
**Example: Opt in to automatic header copying for proxy scenarios**
```js
import got from 'got';
import {pipeline} from 'node:stream/promises';
server.get('/proxy', async (request, response) => {
const gotStream = got.stream('https://example.com', {
copyPipedHeaders: true,
// Explicit headers win over piped headers
headers: {
host: 'example.com',
}
});
await pipeline(request, gotStream, response);
});
```
**Example: Keep it disabled and manually copy only safe headers**
```js
import got from 'got';
import {pipeline} from 'node:stream/promises';
server.get('/proxy', async (request, response) => {
const gotStream = got.stream('https://example.com', {
headers: {
'user-agent': request.headers['user-agent'],
'accept': request.headers['accept'],
// Explicitly NOT copying host, connection, authorization, etc.
}
});
await pipeline(request, gotStream, response);
});
```
### `timeout`
**Type: `object`**
See the [Timeout API](6-timeout.md).
#### **Merge behavior:**
> - Overrides existing properties.
### `retry`
**Type: `object`**
See the [Retry API](7-retry.md).
#### **Merge behavior:**
> - Overrides existing properties.
### `hooks`
**Type: `object`**
See the [Hooks API](9-hooks.md).
#### **Merge behavior:**
> - Merges arrays via `[...hooksArray, ...next]`
### `encoding`
**Type: `string`**\
**Default: `'utf8'`**
[Encoding](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings) to be used on [`setEncoding`](https://nodejs.org/api/stream.html#stream_readable_setencoding_encoding) of the response data.
To get a [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array), you need to set `responseType` to `'buffer'` instead. Don't set this option to `null`.
```js
import got from 'got';
const response = await got('https://httpbin.org/anything', {
encoding: 'base64'
}).text();
console.log(response);
//=> base64 string
```
#### **Note:**
> - This option does not affect streams! Instead, do:
```js
import got from 'got';
const stream = got.stream('https://httpbin.org/anything');
stream.setEncoding('base64');
stream.on('data', console.log);
```
### `responseType`
**Type: `'text' | 'json' | 'buffer'`**\
**Default: `'text'`**
The parsing method.
The promise also has `.text()`, `.json()` and `.buffer()` methods which return another Got promise for the parsed body.\
It's like setting the options to `{responseType: 'json', resolveBodyOnly: true}` but without affecting the main Got promise.
```js
import got from 'got';
const responsePromise = got('https://httpbin.org/anything');
const bufferPromise = responsePromise.buffer();
const jsonPromise = responsePromise.json();
const [response, buffer, json] = await Promise.all([responsePromise, bufferPromise, jsonPromise]);
// `response` is an instance of Got Response
// `buffer` is an instance of Uint8Array
// `json` is an object
```
> [!NOTE]
> When using streams, this option is ignored.
> [!NOTE]
> `'buffer'` will return the raw body bytes as a `Uint8Array`. Any modifications will also alter the result of `.text()` and `.json()`. Before overwriting it, please copy it first via `new Uint8Array(buffer)`.\
> See https://github.com/nodejs/node/issues/27080
### `resolveBodyOnly`
**Type: `boolean`**\
**Default: `false`**
If `true`, the promise will return the [Response body](3-streams.md#response-2) instead of the [Response object](3-streams.md#response-2).
```js
import got from 'got';
const url = 'https://httpbin.org/anything';
// This:
const body = await got(url).json();
// is semantically the same as this:
const body = await got(url, {responseType: 'json', resolveBodyOnly: true});
```
### `context`
**Type: `object`**\
**Default: `{}`**
**Note:**
> - Non-enumerable properties inside are **not** merged.
Contains user data. It's very useful for storing auth tokens:
```js
import got from 'got';
const instance = got.extend({
hooks: {
beforeRequest: [
options => {
if (typeof options.context.token !== 'string') {
throw new Error('Token required');
}
options.headers.token = options.context.token;
}
]
}
});
const context = {
token: 'secret'
};
const {headers} = await instance('https://httpbin.org/headers', {context}).json();
console.log(headers);
//=> {token: 'secret', …}
```
This option is enumerable. In order to define non-enumerable properties inside, do the following:
```js
import got from 'got';
const context = {};
Object.defineProperties(context, {
token: {
value: 'secret',
enumerable: false,
configurable: true,
writable: true
}
});
const instance = got.extend({context});
console.log(instance.defaults.options.context);
//=> {}
```
#### **Merge behavior:**
> - Overrides existing properties.
### `cookieJar`
**Type: object | [tough.cookieJar](https://github.com/salesforce/tough-cookie#cookiejar)**
#### **Note:**
> - Setting this option will result in the `cookie` header being overwritten.
Cookie support. Handles parsing and storing automatically.
```js
import got from 'got';
import {CookieJar} from 'tough-cookie';
const cookieJar = new CookieJar();
await cookieJar.setCookie('foo=bar', 'https://example.com');
await got('https://example.com', {cookieJar});
```
#### `cookieJar.setCookie`
**Type: `(rawCookie: string, url: string) => void | Promise`**
See [ToughCookie API](https://github.com/salesforce/tough-cookie#setcookiecookieorstring-currenturl-options-cberrcookie) for more information.
#### `cookieJar.getCookieString`
**Type: `(currentUrl: string) => string | Promise`**
See [ToughCookie API](https://github.com/salesforce/tough-cookie#getcookiestring) for more information.
### `ignoreInvalidCookies`
**Type: `boolean`**\
**Default: `false`**
Ignore invalid cookies instead of throwing an error.\
Only useful when the `cookieJar` option has been set.
#### **Note:**
> - This is not recommended! Use at your own risk.
### `followRedirect`
**Type: `boolean | (response: PlainResponse) => boolean`**\
**Default: `true`**
Whether redirect responses should be followed automatically.
Optionally, pass a function to dynamically decide based on the response object.
#### **Note:**
> - If a `303` is sent by the server in response to any request type (POST, DELETE, etc.), Got will request the resource pointed to in the location header via GET.\
> This is in accordance with the [specification](https://tools.ietf.org/html/rfc7231#section-6.4.4). You can optionally turn on this behavior also for other redirect codes - see [`methodRewriting`](#methodrewriting).
> - On cross-origin redirects, Got strips `host`, `cookie`, `cookie2`, `authorization`, and `proxy-authorization`, as well as any credentials embedded in the URL.
> - `307` and `308` redirects preserve the request method and replayable body, even across origins, as required by the specification. `QUERY` requests also preserve replayable bodies on `301` and `302` redirects because `QUERY` is safe and idempotent. Got fails instead of following when the body cannot be replayed.
> - Other cross-origin redirects can drop the request body and request body headers to avoid forwarding payloads to another origin.
> - When a redirect rewrites the request to `GET`, Got also strips request body headers.
> - Use [`hooks.beforeRedirect`](9-hooks.md#beforeredirect) for app-specific sensitive headers.
```js
import got from 'got';
const instance = got.extend({followRedirect: false});
const response = await instance('http://google.com');
console.log(response.headers.location);
//=> 'https://google.com'
```
### `maxRedirects`
**Type: `number`**\
**Default: `10`**
If exceeded, the request will be aborted and a [`MaxRedirectsError`](8-errors.md#maxredirectserror) will be thrown.
```js
import got from 'got';
const instance = got.extend({maxRedirects: 3});
try {
await instance('https://nghttp2.org/httpbin/absolute-redirect/5');
} catch (error) {
//=> 'Redirected 3 times. Aborting.'
console.log(error.message);
}
```
### `decompress`
**Type: `boolean`**\
**Default: `true`**
Decompress the response automatically. This will set the `accept-encoding` header to `gzip, deflate, br` (and `zstd` on Node.js >= 22.15.0).
If disabled, a compressed response is returned as a `Uint8Array`. This may be useful if you want to handle decompression yourself.
> [!NOTE]
> Zstandard (`zstd`) compression support is available on Node.js >= 22.15.0 and will be automatically enabled when available.
```js
import got from 'got';
const response = await got('https://google.com');
console.log(response.headers['content-encoding']);
//=> 'gzip'
```
### `strictContentLength`
**Type: `boolean`**\
**Default: `true`**
Throw an error if the server response's `content-length` header value doesn't match the number of bytes received.
This is useful for detecting truncated responses and follows RFC 9112 requirements for message completeness.
> [!NOTE]
> - Responses without a `content-length` header are not validated.
> - When enabled and validation fails, a [`ReadError`](8-errors.md#readerror) with code `ERR_HTTP_CONTENT_LENGTH_MISMATCH` will be thrown.
### `dnsLookup`
**Type: `Function`**\
**Default: [`dns.lookup`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback)**
Custom DNS resolution logic.
The function signature is the same as `dns.lookup`.
### `dnsCache`
**Type: {lookup: Function; clear?: Function} | boolean**
A DNS cache instance used for making DNS lookups.\
Useful when making lots of requests to different public hostnames.
Set to `true` to use Got's shared DNS cache.
When using `got.extend()`, set to `false` to opt out of a DNS cache configured by the parent instance.
**Note:**
> - This should stay disabled when making requests to internal hostnames such as localhost, database.local etc.
> - Got's built-in DNS cache uses `dns.resolve4(…)` and `dns.resolve6(…)` under the hood and falls back to `dns.lookup(…)` when no DNS records are found, which may lead to additional delay.
> - Because Got's built-in DNS cache resolves A and AAAA records separately, it cannot preserve OS-specific `verbatim` address ordering from `dns.lookup(…)`.
> - If present, `clear(hostname?)` can be called by user code to clear cached entries.
### `dnsLookupIpVersion`
**Type: `4 | 6`**\
**Default: `undefined`**
The IP version to use. Specifying `undefined` will use the default configuration.
### `request`
**Type: Function<[ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest) | [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) | undefined> | AsyncFunction<[ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest) | [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) | undefined>**\
**Default: Got's built-in HTTP/1.1 or HTTP/2 request implementation**
Custom request function.
Returning `undefined` (or resolving to `undefined`) will fall back to Got's native request implementation.
### `cache`
**Type: `object | false`**\
**Default: `false`**
[Cache adapter instance](cache.md) for storing cached response data.
### `cacheOptions`
**Type: `object`**\
**Default: `{}`**
[Cache options](https://github.com/kornelski/http-cache-semantics#constructor-options) used for the specified request.
### `http2`
**Type: `boolean`**\
**Default: `false`**
If `true`, Got will use its built-in HTTP/2 client when ALPN selects HTTP/2.
**Note:**
> - ALPN negotiation will take place in order to determine if the server actually supports HTTP/2. If it doesn't, HTTP/1.1 will be used. When a custom `agent.https` instance is set, Got uses that native HTTPS agent directly and skips HTTP/2 negotiation.
**Note:**
> - If the `request` option returns a request or response, it controls the transport and Got's HTTP/2 client is bypassed. Return `undefined` to fall back to Got's built-in transport.
**Note:**
> - There is no direct [`h2c` Upgrade](https://datatracker.ietf.org/doc/html/rfc9113#section-11.2) support. However, you can provide a `h2session` option in a `beforeRequest` hook. See [an example](examples/h2c.js).
```js
import got from 'got';
const {statusCode} = await got(
'https://httpbin.org/anything',
{
http2: true
}
);
console.log(statusCode);
//=> 200
```
### `agent`
**Type: `object`**\
**Default: `{}`**
An object with `http`, `https` and `http2` properties.
Got will automatically resolve the protocol and use the corresponding agent. HTTP/2 uses Got's internal session pool by default. Set `agent.http2` to `false` to disable HTTP/2 session pooling for the request. `agent.http2` is only a pooling opt-out flag; custom HTTP/2 agents are not part of the public API. When `http2` is enabled, a custom `agent.https` instance makes Got use the native HTTP/1.1 request path because Got's built-in HTTP/2 session pool does not support custom HTTPS agents.
```js
{
http: http.globalAgent,
https: https.globalAgent
}
```
### `throwHttpErrors`
**Type: `boolean`**\
**Default: `true`**
If `true`, it will [throw](8-errors.md#httperror) when the status code is not `2xx` / `3xx`.
If this is disabled, requests that encounter an error status code will be resolved with the response instead of throwing. This may be useful if you are checking for resource availability and are expecting error responses.
### `username`
**Type: `string`**\
**Default: `''`**
The `username` used for [Basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
### `password`
**Type: `string`**\
**Default: `''`**
The `password` used for [Basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
### `localAddress`
**Type: `string | undefined`**\
**Default: `undefined`**
The local IP address used to make the request.
### `createConnection`
**Type: `Function | undefined`**\
**Default: `undefined`**
The function used to retrieve a `net.Socket` instance when the `agent` option is not used.
### `https`
**Type: `object`**
See [Advanced HTTPS API](5-https.md).
### `pagination`
**Type: `object`**
See [Pagination API](4-pagination.md).
### `setHost`
**Type: `boolean`**\
**Default: `true`**
Specifies whether or not to automatically add the `Host` header.
### `maxHeaderSize`
**Type: `number | undefined`**\
**Default: `undefined`**
Optionally overrides the value of [`--max-http-header-size`](https://nodejs.org/api/cli.html#cli_max_http_header_size_size) (default 16KB: `16384`).
### `methodRewriting`
**Type: `boolean`**\
**Default: `false`**
Specifies if the HTTP request method should be [rewritten as `GET`](https://tools.ietf.org/html/rfc7231#section-6.4) on redirects.
As the [specification](https://tools.ietf.org/html/rfc7231#section-6.4) prefers to rewrite the HTTP method only on `303` responses, this is Got's default behavior. Cross-origin `301` and `302` redirects also rewrite `POST` requests to `GET` by default to avoid forwarding request bodies to another origin. Setting `methodRewriting` to `true` will also rewrite same-origin `301` and `302` responses, as allowed by the spec. This is the behavior followed by `curl` and browsers.
**Note:**
> - Got never performs method rewriting on `307` and `308` responses, as this is [explicitly prohibited by the specification](https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7).
### `enableUnixSockets`
**Type: `boolean`**\
**Default: `false`**
When enabled, requests can also be sent via [UNIX Domain Sockets](https://serverfault.com/questions/124517/what-is-the-difference-between-unix-sockets-and-tcp-ip-sockets).
> **Warning**
> Make sure you do your own URL sanitizing if you accept untrusted user input for the URL.
Use the following URL scheme: `PROTOCOL://unix:SOCKET:PATH`
- `PROTOCOL` - `http` or `https`
- `SOCKET` - Absolute path to a UNIX domain socket, for example: `/var/run/docker.sock`
- `PATH` - Request path, for example: `/v2/keys`
```js
import got from 'got';
await got('http://unix:/var/run/docker.sock:/containers/json', {enableUnixSockets: true});
// Or without protocol (HTTP by default)
await got('unix:/var/run/docker.sock:/containers/json', {enableUnixSockets: true});
// Enable Unix sockets for the whole instance.
const gotWithUnixSockets = got.extend({enableUnixSockets: true});
await gotWithUnixSockets('http://unix:/var/run/docker.sock:/containers/json');
```
## Methods
### `options.merge(other: Options | OptionsInit)`
Merges `other` into the current instance.
If you look at the [source code](../source/core/options.ts), you will notice that options track internal merge state.\
Setters work a bit differently while merge is in progress.
### `options.toJSON()`
Returns a new plain object that can be stored as [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior).
### `options.createNativeRequestOptions()`
Creates a new object for native Node.js HTTP request options.
In other words, this translates Got options into Node.js options.
**Note:**
> - Some other stuff, such as timeouts, is handled internally by Got.
### `options.getRequestFunction()`
Returns a [`http.request`-like](https://nodejs.org/api/http.html#http_http_request_url_options_callback) function used to make the request.
### `options.freeze()`
Makes the entire `Options` instance read-only.