UNPKG

73.7 kBMarkdownView Raw
1<div align="center">
2 <br>
3 <br>
4 <img width="360" src="media/logo.svg" alt="Got">
5 <br>
6 <br>
7 <br>
8 <p align="center">Huge thanks to <a href="https://moxy.studio"><img src="https://sindresorhus.com/assets/thanks/moxy-logo.svg" width="150"></a> for sponsoring Sindre Sorhus!
9 </p>
10 <br>
11 <br>
12</div>
13
14> Human-friendly and powerful HTTP request library for Node.js
15
16[![Build Status: Linux](https://travis-ci.com/sindresorhus/got.svg?branch=master)](https://travis-ci.com/github/sindresorhus/got)
17[![Coverage Status](https://coveralls.io/repos/github/sindresorhus/got/badge.svg?branch=master)](https://coveralls.io/github/sindresorhus/got?branch=master)
18[![Downloads](https://img.shields.io/npm/dm/got.svg)](https://npmjs.com/got)
19[![Install size](https://packagephobia.now.sh/badge?p=got)](https://packagephobia.now.sh/result?p=got)
20
21[Moving from Request?](documentation/migration-guides.md) [*(Note that Request is unmaintained)*](https://github.com/request/request/issues/3142)
22
23[See how Got compares to other HTTP libraries](#comparison)
24
25For browser usage, we recommend [Ky](https://github.com/sindresorhus/ky) by the same people.
26
27## Highlights
28
29- [Promise API](#api)
30- [Stream API](#streams)
31- [Pagination API](#pagination)
32- [HTTP2 support](#http2)
33- [Request cancelation](#aborting-the-request)
34- [RFC compliant caching](#cache-adapters)
35- [Follows redirects](#followredirect)
36- [Retries on failure](#retry)
37- [Progress events](#onuploadprogress-progress)
38- [Handles gzip/deflate/brotli](#decompress)
39- [Timeout handling](#timeout)
40- [Errors with metadata](#errors)
41- [JSON mode](#json-mode)
42- [WHATWG URL support](#url)
43- [HTTPS API](#https)
44- [Hooks](#hooks)
45- [Instances with custom defaults](#instances)
46- [Types](#types)
47- [Composable](documentation/advanced-creation.md#merging-instances)
48- [Plugins](documentation/lets-make-a-plugin.md)
49- [Used by 4K+ packages and 1.8M+ repos](https://github.com/sindresorhus/got/network/dependents)
50- [Actively maintained](https://github.com/sindresorhus/got/graphs/contributors)
51
52## Install
53
54```
55$ npm install got
56```
57
58## Usage
59
60###### Promise
61
62```js
63const got = require('got');
64
65(async () => {
66 try {
67 const response = await got('https://sindresorhus.com');
68 console.log(response.body);
69 //=> '<!doctype html> ...'
70 } catch (error) {
71 console.log(error.response.body);
72 //=> 'Internal server error ...'
73 }
74})();
75```
76
77###### JSON
78
79```js
80const got = require('got');
81
82(async () => {
83 const {body} = await got.post('https://httpbin.org/anything', {
84 json: {
85 hello: 'world'
86 },
87 responseType: 'json'
88 });
89
90 console.log(body.data);
91 //=> {hello: 'world'}
92})();
93```
94
95See [JSON mode](#json-mode) for more details.
96
97###### Streams
98
99```js
100const stream = require('stream');
101const {promisify} = require('util');
102const fs = require('fs');
103const got = require('got');
104
105const pipeline = promisify(stream.pipeline);
106
107(async () => {
108 await pipeline(
109 got.stream('https://sindresorhus.com'),
110 fs.createWriteStream('index.html')
111 );
112
113 // For POST, PUT, and PATCH methods `got.stream` returns a `stream.Writable`
114 await pipeline(
115 fs.createReadStream('index.html'),
116 got.stream.post('https://sindresorhus.com')
117 );
118})();
119```
120
121**Tip:** `from.pipe(to)` doesn't forward errors. Instead, use [`stream.pipeline(from, ..., to, callback)`](https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback).
122
123**Note:** While `got.post('https://example.com')` resolves, `got.stream.post('https://example.com')` will hang indefinitely until a body is provided. If there's no body on purpose, remember to `.end()` the stream or set the [`body`](#body) option to an empty string.
124
125### API
126
127It's a `GET` request by default, but can be changed by using different methods or via [`options.method`](#method).
128
129**By default, Got will retry on failure. To disable this option, set [`options.retry`](#retry) to `0`.**
130
131#### got(url?, options?)
132
133Returns a Promise giving a [Response object](#response) or a [Got Stream](#streams-1) if `options.isStream` is set to true.
134
135##### url
136
137Type: `string | object`
138
139The URL to request, as a string, a [`https.request` options object](https://nodejs.org/api/https.html#https_https_request_options_callback), or a [WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url).
140
141Properties from `options` will override properties in the parsed `url`.
142
143If no protocol is specified, it will throw a `TypeError`.
144
145**Note:** The query string is **not** parsed as search params. Example:
146
147```
148got('https://example.com/?query=a b'); //=> https://example.com/?query=a%20b
149got('https://example.com/', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b
150
151// The query string is overridden by `searchParams`
152got('https://example.com/?query=a b', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b
153```
154
155##### options
156
157Type: `object`
158
159Any of the [`https.request`](https://nodejs.org/api/https.html#https_https_request_options_callback) options.
160
161**Note:** Legacy URL support is disabled. `options.path` is supported only for backwards compatibility. Use `options.pathname` and `options.searchParams` instead. `options.auth` has been replaced with `options.username` & `options.password`.
162
163###### method
164
165Type: `string`\
166Default: `GET`
167
168The HTTP method used to make the request.
169
170###### prefixUrl
171
172Type: `string | URL`
173
174When specified, `prefixUrl` will be prepended to `url`. The prefix can be any valid URL, either relative or absolute.\
175A trailing slash `/` is optional - one will be added automatically.
176
177**Note:** `prefixUrl` will be ignored if the `url` argument is a URL instance.
178
179**Note:** Leading slashes in `input` are disallowed when using this option 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.
180
181**Tip:** Useful when used with [`got.extend()`](#custom-endpoints) to create niche-specific Got instances.
182
183**Tip:** You can change `prefixUrl` using hooks as long as the URL still includes the `prefixUrl`. If the URL doesn't include it anymore, it will throw.
184
185```js
186const got = require('got');
187
188(async () => {
189 await got('unicorn', {prefixUrl: 'https://cats.com'});
190 //=> 'https://cats.com/unicorn'
191
192 const instance = got.extend({
193 prefixUrl: 'https://google.com'
194 });
195
196 await instance('unicorn', {
197 hooks: {
198 beforeRequest: [
199 options => {
200 options.prefixUrl = 'https://cats.com';
201 }
202 ]
203 }
204 });
205 //=> 'https://cats.com/unicorn'
206})();
207```
208
209###### headers
210
211Type: `object`\
212Default: `{}`
213
214Request headers.
215
216Existing headers will be overwritten. Headers set to `undefined` will be omitted.
217
218###### isStream
219
220Type: `boolean`\
221Default: `false`
222
223Returns a `Stream` instead of a `Promise`. This is equivalent to calling `got.stream(url, options?)`.
224
225###### body
226
227Type: `string | Buffer | stream.Readable` or [`form-data` instance](https://github.com/form-data/form-data)
228
229**Note #1:** The `body` option cannot be used with the `json` or `form` option.
230
231**Note #2:** If you provide this option, `got.stream()` will be read-only.
232
233**Note #3:** If you provide a payload with the `GET` or `HEAD` method, it will throw a `TypeError` unless the method is `GET` and the `allowGetBody` option is set to `true`.
234
235**Note #4:** This option is not enumerable and will not be merged with the instance defaults.
236
237The `content-length` header will be automatically set if `body` is a `string` / `Buffer` / `fs.createReadStream` instance / [`form-data` instance](https://github.com/form-data/form-data), and `content-length` and `transfer-encoding` are not manually set in `options.headers`.
238
239###### json
240
241Type: `object | Array | number | string | boolean | null` *(JSON-serializable values)*
242
243**Note #1:** If you provide this option, `got.stream()` will be read-only.\
244**Note #2:** This option is not enumerable and will not be merged with the instance defaults.
245
246JSON body. If the `Content-Type` header is not set, it will be set to `application/json`.
247
248###### context
249
250Type: `object`
251
252User data. In contrast to other options, `context` is not enumerable.
253
254**Note:** The object is never merged, it's just passed through. Got will not modify the object in any way.
255
256It's very useful for storing auth tokens:
257
258```js
259const got = require('got');
260
261const instance = got.extend({
262 hooks: {
263 beforeRequest: [
264 options => {
265 if (!options.context || !options.context.token) {
266 throw new Error('Token required');
267 }
268
269 options.headers.token = options.context.token;
270 }
271 ]
272 }
273});
274
275(async () => {
276 const context = {
277 token: 'secret'
278 };
279
280 const response = await instance('https://httpbin.org/headers', {context});
281
282 // Let's see the headers
283 console.log(response.body);
284})();
285```
286
287###### responseType
288
289Type: `string`\
290Default: `'text'`
291
292**Note:** When using streams, this option is ignored.
293
294The parsing method. Can be `'text'`, `'json'` or `'buffer'`.
295
296The promise also has `.text()`, `.json()` and `.buffer()` methods which return another Got promise for the parsed body.\
297It's like setting the options to `{responseType: 'json', resolveBodyOnly: true}` but without affecting the main Got promise.
298
299Example:
300
301```js
302(async () => {
303 const responsePromise = got(url);
304 const bufferPromise = responsePromise.buffer();
305 const jsonPromise = responsePromise.json();
306
307 const [response, buffer, json] = Promise.all([responsePromise, bufferPromise, jsonPromise]);
308 // `response` is an instance of Got Response
309 // `buffer` is an instance of Buffer
310 // `json` is an object
311})();
312```
313
314```js
315// This
316const body = await got(url).json();
317
318// is semantically the same as this
319const body = await got(url, {responseType: 'json', resolveBodyOnly: true});
320```
321
322###### parseJson
323
324Type: `(text: string) => unknown`\
325Default: `(text: string) => JSON.parse(text)`
326
327A function used to parse JSON responses.
328
329<details>
330<summary>Example</summary>
331
332Using [`bourne`](https://github.com/hapijs/bourne) to prevent prototype pollution:
333
334```js
335const got = require('got');
336const Bourne = require('@hapi/bourne');
337
338(async () => {
339 const parsed = await got('https://example.com', {
340 parseJson: text => Bourne.parse(text)
341 }).json();
342
343 console.log(parsed);
344})();
345```
346</details>
347
348###### stringifyJson
349
350Type: `(object: unknown) => string`\
351Default: `(object: unknown) => JSON.stringify(object)`
352
353A function used to stringify the body of JSON requests.
354
355<details>
356<summary>Examples</summary>
357
358Ignore properties starting with `_`:
359
360```js
361const got = require('got');
362
363(async () => {
364 await got.post('https://example.com', {
365 stringifyJson: object => JSON.stringify(object, (key, value) => {
366 if (key.startsWith('_')) {
367 return;
368 }
369
370 return value;
371 }),
372 json: {
373 some: 'payload',
374 _ignoreMe: 1234
375 }
376 });
377})();
378```
379
380All numbers as strings:
381
382```js
383const got = require('got');
384
385(async () => {
386 await got.post('https://example.com', {
387 stringifyJson: object => JSON.stringify(object, (key, value) => {
388 if (typeof value === 'number') {
389 return value.toString();
390 }
391
392 return value;
393 }),
394 json: {
395 some: 'payload',
396 number: 1
397 }
398 });
399})();
400```
401</details>
402
403###### resolveBodyOnly
404
405Type: `boolean`\
406Default: `false`
407
408When set to `true` the promise will return the [Response body](#body-1) instead of the [Response](#response) object.
409
410###### cookieJar
411
412Type: `object` | [`tough.CookieJar` instance](https://github.com/salesforce/tough-cookie#cookiejar)
413
414**Note:** If you provide this option, `options.headers.cookie` will be overridden.
415
416Cookie support. You don't have to care about parsing or how to store them. [Example](#cookies).
417
418###### cookieJar.setCookie
419
420Type: `Function<Promise>`
421
422The function takes two arguments: `rawCookie` (`string`) and `url` (`string`).
423
424###### cookieJar.getCookieString
425
426Type: `Function<Promise>`
427
428The function takes one argument: `url` (`string`).
429
430###### ignoreInvalidCookies
431
432Type: `boolean`\
433Default: `false`
434
435Ignore invalid cookies instead of throwing an error. Only useful when the `cookieJar` option has been set. Not recommended.
436
437###### encoding
438
439Type: `string`\
440Default: `'utf8'`
441
442[Encoding](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings) to be used on `setEncoding` of the response data.
443
444To get a [`Buffer`](https://nodejs.org/api/buffer.html), you need to set [`responseType`](#responseType) to `buffer` instead. Don't set this option to `null`.
445
446**Note:** This doesn't affect streams! Instead, you need to do `got.stream(...).setEncoding(encoding)`.
447
448###### form
449
450Type: `object`
451
452**Note #1:** If you provide this option, `got.stream()` will be read-only.\
453**Note #2:** This option is not enumerable and will not be merged with the instance defaults.
454
455The form body is converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
456
457If the `Content-Type` header is not present, it will be set to `application/x-www-form-urlencoded`.
458
459###### searchParams
460
461Type: `string | object<string, string | number> | URLSearchParams`
462
463Query string that will be added to the request URL. This will override the query string in `url`.
464
465If you need to pass in an array, you can do it using a `URLSearchParams` instance:
466
467```js
468const got = require('got');
469
470const searchParams = new URLSearchParams([['key', 'a'], ['key', 'b']]);
471
472got('https://example.com', {searchParams});
473
474console.log(searchParams.toString());
475//=> 'key=a&key=b'
476```
477
478There are some exceptions in regards to `URLSearchParams` behavior:
479
480**Note #1:** `null` values are not stringified, an empty string is used instead.
481
482**Note #2:** `undefined` values are not stringified, the entry is skipped instead.
483
484###### timeout
485
486Type: `number | object`
487
488Milliseconds to wait for the server to end the response before aborting the request with [`got.TimeoutError`](#gottimeouterror) error (a.k.a. `request` property). By default, there's no timeout.
489
490This also accepts an `object` with the following fields to constrain the duration of each phase of the request lifecycle:
491
492- `lookup` starts when a socket is assigned and ends when the hostname has been resolved. Does not apply when using a Unix domain socket.
493- `connect` starts when `lookup` completes (or when the socket is assigned if lookup does not apply to the request) and ends when the socket is connected.
494- `secureConnect` starts when `connect` completes and ends when the handshaking process completes (HTTPS only).
495- `socket` starts when the socket is connected. See [request.setTimeout](https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback).
496- `response` starts when the request has been written to the socket and ends when the response headers are received.
497- `send` starts when the socket is connected and ends with the request has been written to the socket.
498- `request` starts when the request is initiated and ends when the response's end event fires.
499
500###### retry
501
502Type: `number | object`\
503Default:
504- limit: `2`
505- calculateDelay: `({attemptCount, retryOptions, error, computedValue}) => computedValue | Promise<computedValue>`
506- methods: `GET` `PUT` `HEAD` `DELETE` `OPTIONS` `TRACE`
507- statusCodes: [`408`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) [`413`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) [`429`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) [`500`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) [`502`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) [`503`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) [`504`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504) [`521`](https://support.cloudflare.com/hc/en-us/articles/115003011431#521error) [`522`](https://support.cloudflare.com/hc/en-us/articles/115003011431#522error) [`524`](https://support.cloudflare.com/hc/en-us/articles/115003011431#524error)
508- maxRetryAfter: `undefined`
509- errorCodes: `ETIMEDOUT` `ECONNRESET` `EADDRINUSE` `ECONNREFUSED` `EPIPE` `ENOTFOUND` `ENETUNREACH` `EAI_AGAIN`
510
511An object representing `limit`, `calculateDelay`, `methods`, `statusCodes`, `maxRetryAfter` and `errorCodes` fields for maximum retry count, retry handler, allowed methods, allowed status codes, maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time and allowed error codes.
512
513**Note:** When using streams, this option is ignored. If the connection is reset when downloading, you need to catch the error and clear the file you were writing into to prevent duplicated content.
514
515If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`.\
516If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will cancel the request.
517
518Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 1).
519
520The `calculateDelay` property is a `function` that receives an object with `attemptCount`, `retryOptions`, `error` and `computedValue` properties for current retry count, the retry options, error and default computed value. The function must return a delay in milliseconds (or a Promise resolving with it) (`0` return value cancels retry).
521
522By default, it retries *only* on the specified methods, status codes, and on these network errors:
523- `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached.
524- `ECONNRESET`: Connection was forcibly closed by a peer.
525- `EADDRINUSE`: Could not bind to any free port.
526- `ECONNREFUSED`: Connection was refused by the server.
527- `EPIPE`: The remote side of the stream being written has been closed.
528- `ENOTFOUND`: Couldn't resolve the hostname to an IP address.
529- `ENETUNREACH`: No internet connection.
530- `EAI_AGAIN`: DNS lookup timed out.
531
532###### followRedirect
533
534Type: `boolean`\
535Default: `true`
536
537Defines if redirect responses should be followed automatically.
538
539Note that if a `303` is sent by the server in response to any request type (`POST`, `DELETE`, etc.), Got will automatically request the resource pointed to in the location header via `GET`. This is in accordance with [the spec](https://tools.ietf.org/html/rfc7231#section-6.4.4).
540
541###### methodRewriting
542
543Type: `boolean`\
544Default: `true`
545
546By default, redirects will use [method rewriting](https://tools.ietf.org/html/rfc7231#section-6.4). For example, when sending a POST request and receiving a `302`, it will resend the body to the new location using the same HTTP method (`POST` in this case).
547
548###### allowGetBody
549
550Type: `boolean`\
551Default: `false`
552
553**Note:** The [RFC 7321](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)**.
554
555Set this to `true` to allow sending body for the `GET` method. However, the [HTTP/2 specification](https://tools.ietf.org/html/rfc7540#section-8.1.3) says that `An HTTP GET request includes request header fields and no payload body`, therefore when using the HTTP/2 protocol this option will have no effect. This option is only meant to interact with non-compliant servers when you have no other choice.
556
557###### maxRedirects
558
559Type: `number`\
560Default: `10`
561
562If exceeded, the request will be aborted and a `MaxRedirectsError` will be thrown.
563
564###### decompress
565
566Type: `boolean`\
567Default: `true`
568
569Decompress the response automatically. This will set the `accept-encoding` header to `gzip, deflate, br` on Node.js 11.7.0+ or `gzip, deflate` for older Node.js versions, unless you set it yourself.
570
571Brotli (`br`) support requires Node.js 11.7.0 or later.
572
573If this is disabled, a compressed response is returned as a `Buffer`. This may be useful if you want to handle decompression yourself or stream the raw compressed data.
574
575###### cache
576
577Type: `object | false`\
578Default: `false`
579
580[Cache adapter instance](#cache-adapters) for storing cached response data.
581
582###### dnsCache
583
584Type: `CacheableLookup | false`\
585Default: `false`
586
587An instance of [`CacheableLookup`](https://github.com/szmarczak/cacheable-lookup) used for making DNS lookups. Useful when making lots of requests to different *public* hostnames.
588
589**Note:** This should stay disabled when making requests to internal hostnames such as `localhost`, `database.local` etc.\
590`CacheableLookup` uses `dns.resolver4(..)` and `dns.resolver6(...)` under the hood and fall backs to `dns.lookup(...)` when the first two fail, which may lead to additional delay.
591
592###### dnsLookupIpVersion
593
594Type: `'auto' | 'ipv4' | 'ipv6'`\
595Default: `'auto'`
596
597Indicates which DNS record family to use.\
598Values:
599 - `auto`: IPv4 (if present) or IPv6
600 - `ipv4`: Only IPv4
601 - `ipv6`: Only IPv6
602
603Note: If you are using the undocumented option `family`, `dnsLookupIpVersion` will override it.
604
605```js
606// `api6.ipify.org` will be resolved as IPv4 and the request will be over IPv4 (the website will respond with your public IPv4)
607await got('https://api6.ipify.org', {
608 dnsLookupIpVersion: 'ipv4'
609});
610
611// `api6.ipify.org` will be resolved as IPv6 and the request will be over IPv6 (the website will respond with your public IPv6)
612await got('https://api6.ipify.org', {
613 dnsLookupIpVersion: 'ipv6'
614});
615```
616
617###### request
618
619Type: `Function`\
620Default: `http.request | https.request` *(Depending on the protocol)*
621
622Custom request function. The main purpose of this is to [support HTTP2 using a wrapper](https://github.com/szmarczak/http2-wrapper).
623
624###### http2
625
626Type: `boolean`\
627Default: `false`
628
629If set to `true`, Got will additionally accept HTTP2 requests.\
630It will choose either HTTP/1.1 or HTTP/2 depending on the ALPN protocol.
631
632**Note:** Overriding `options.request` will disable HTTP2 support.
633
634**Note:** This option will default to `true` in the next upcoming major release.
635
636```js
637const got = require('got');
638
639(async () => {
640 const {headers} = await got('https://nghttp2.org/httpbin/anything', {http2: true});
641 console.log(headers.via);
642 //=> '2 nghttpx'
643})();
644```
645
646###### throwHttpErrors
647
648Type: `boolean`\
649Default: `true`
650
651Determines if a [`got.HTTPError`](#gothttperror) is thrown for unsuccessful responses.
652
653If 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.
654
655###### agent
656
657Type: `object`
658
659An object representing `http`, `https` and `http2` keys for [`http.Agent`](https://nodejs.org/api/http.html#http_class_http_agent), [`https.Agent`](https://nodejs.org/api/https.html#https_class_https_agent) and [`http2wrapper.Agent`](https://github.com/szmarczak/http2-wrapper#new-http2agentoptions) instance. This is necessary because a request to one protocol might redirect to another. In such a scenario, Got will switch over to the right protocol agent for you.
660
661If a key is not present, it will default to a global agent.
662
663```js
664const got = require('got');
665const HttpAgent = require('agentkeepalive');
666const {HttpsAgent} = HttpAgent;
667
668got('https://sindresorhus.com', {
669 agent: {
670 http: new HttpAgent(),
671 https: new HttpsAgent()
672 }
673});
674```
675
676###### hooks
677
678Type: `object<string, Function[]>`
679
680Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially.
681
682###### hooks.init
683
684Type: `Function[]`\
685Default: `[]`
686
687Called with plain [request options](#options), right before their normalization. This is especially useful in conjunction with [`got.extend()`](#instances) when the input needs custom handling.
688
689See the [Request migration guide](documentation/migration-guides.md#breaking-changes) for an example.
690
691**Note #1:** This hook must be synchronous!\
692**Note #2:** Errors in this hook will be converted into an instances of [`RequestError`](#got.requesterror).\
693**Note #3:** The options object may not have a `url` property. To modify it, use a `beforeRequest` hook instead.
694
695###### hooks.beforeRequest
696
697Type: `Function[]`\
698Default: `[]`
699
700Called with [normalized](source/core/index.ts) [request options](#options). Got will make no further changes to the request before it is sent. This is especially useful in conjunction with [`got.extend()`](#instances) when you want to create an API client that, for example, uses HMAC-signing.
701
702See the [AWS section](#aws) for an example.
703
704**Tip:** You can override the `request` function by returning a [`ClientRequest`-like](https://nodejs.org/api/http.html#http_class_http_clientrequest) instance or a [`IncomingMessage`-like](https://nodejs.org/api/http.html#http_class_http_incomingmessage) instance. This is very useful when creating a custom cache mechanism.
705
706###### hooks.beforeRedirect
707
708Type: `Function[]`\
709Default: `[]`
710
711Called with [normalized](source/core/index.ts) [request options](#options) and the redirect [response](#response). Got will make no further changes to the request. This is especially useful when you want to avoid dead sites. Example:
712
713```js
714const got = require('got');
715
716got('https://example.com', {
717 hooks: {
718 beforeRedirect: [
719 (options, response) => {
720 if (options.hostname === 'deadSite') {
721 options.hostname = 'fallbackSite';
722 }
723 }
724 ]
725 }
726});
727```
728
729###### hooks.beforeRetry
730
731Type: `Function[]`\
732Default: `[]`
733
734**Note:** When using streams, this hook is ignored.
735
736Called with [normalized](source/normalize-arguments.ts) [request options](#options), the error and the retry count. Got will make no further changes to the request. This is especially useful when some extra work is required before the next try. Example:
737
738```js
739const got = require('got');
740
741got.post('https://example.com', {
742 hooks: {
743 beforeRetry: [
744 (options, error, retryCount) => {
745 if (error.response.statusCode === 413) { // Payload too large
746 options.body = getNewBody();
747 }
748 }
749 ]
750 }
751});
752```
753
754**Note:** When retrying in a `afterResponse` hook, all remaining `beforeRetry` hooks will be called without the `error` and `retryCount` arguments.
755
756###### hooks.afterResponse
757
758Type: `Function[]`\
759Default: `[]`
760
761**Note:** When using streams, this hook is ignored.
762
763Called with [response object](#response) and a retry function. Calling the retry function will trigger `beforeRetry` hooks.
764
765Each function should return the response. This is especially useful when you want to refresh an access token. Example:
766
767```js
768const got = require('got');
769
770const instance = got.extend({
771 hooks: {
772 afterResponse: [
773 (response, retryWithMergedOptions) => {
774 if (response.statusCode === 401) { // Unauthorized
775 const updatedOptions = {
776 headers: {
777 token: getNewToken() // Refresh the access token
778 }
779 };
780
781 // Save for further requests
782 instance.defaults.options = got.mergeOptions(instance.defaults.options, updatedOptions);
783
784 // Make a new retry
785 return retryWithMergedOptions(updatedOptions);
786 }
787
788 // No changes otherwise
789 return response;
790 }
791 ],
792 beforeRetry: [
793 (options, error, retryCount) => {
794 // This will be called on `retryWithMergedOptions(...)`
795 }
796 ]
797 },
798 mutableDefaults: true
799});
800```
801
802###### hooks.beforeError
803
804Type: `Function[]`\
805Default: `[]`
806
807Called with an `Error` instance. The error is passed to the hook right before it's thrown. This is especially useful when you want to have more detailed errors.
808
809**Note:** Errors thrown while normalizing input options are thrown directly and not part of this hook.
810
811```js
812const got = require('got');
813
814got('https://api.github.com/some-endpoint', {
815 hooks: {
816 beforeError: [
817 error => {
818 const {response} = error;
819 if (response && response.body) {
820 error.name = 'GitHubError';
821 error.message = `${response.body.message} (${response.statusCode})`;
822 }
823
824 return error;
825 }
826 ]
827 }
828});
829```
830
831##### pagination
832
833Type: `object`
834
835**Note:** We're [looking for feedback](https://github.com/sindresorhus/got/issues/1052), any ideas on how to improve the API are welcome.
836
837###### pagination.transform
838
839Type: `Function`\
840Default: `response => JSON.parse(response.body)`
841
842A function that transform [`Response`](#response) into an array of items. This is where you should do the parsing.
843
844###### pagination.paginate
845
846Type: `Function`\
847Default: [`Link` header logic](source/index.ts)
848
849The function takes three arguments:
850- `response` - The current response object.
851- `allItems` - An array of the emitted items.
852- `currentItems` - Items from the current response.
853
854It should return an object representing Got options pointing to the next page. The options are merged automatically with the previous request, therefore the options returned `pagination.paginate(...)` must reflect changes only. If there are no more pages, `false` should be returned.
855
856For example, if you want to stop when the response contains less items than expected, you can use something like this:
857
858```js
859const got = require('got');
860
861(async () => {
862 const limit = 10;
863
864 const items = got.paginate('https://example.com/items', {
865 searchParams: {
866 limit,
867 offset: 0
868 },
869 pagination: {
870 paginate: (response, allItems, currentItems) => {
871 const previousSearchParams = response.request.options.searchParams;
872 const previousOffset = previousSearchParams.get('offset');
873
874 if (currentItems.length < limit) {
875 return false;
876 }
877
878 return {
879 searchParams: {
880 ...previousSearchParams,
881 offset: Number(previousOffset) + limit,
882 }
883 };
884 }
885 }
886 });
887
888 console.log('Items from all pages:', items);
889})();
890```
891
892###### pagination.filter
893
894Type: `Function`\
895Default: `(item, allItems, currentItems) => true`
896
897Checks whether the item should be emitted or not.
898
899###### pagination.shouldContinue
900
901Type: `Function`\
902Default: `(item, allItems, currentItems) => true`
903
904Checks whether the pagination should continue.
905
906For example, if you need to stop **before** emitting an entry with some flag, you should use `(item, allItems, currentItems) => !item.flag`. If you want to stop **after** emitting the entry, you should use `(item, allItems, currentItems) => allItems.some(entry => entry.flag)` instead.
907
908###### pagination.countLimit
909
910Type: `number`\
911Default: `Infinity`
912
913The maximum amount of items that should be emitted.
914
915###### pagination.backoff
916
917Type: `number`\
918Default: `0`
919
920Milliseconds to wait before the next request is triggered.
921
922###### pagination.requestLimit
923
924Type: `number`\
925Default: `10000`
926
927The maximum amount of request that should be triggered. [Retries on failure](#retry) are not counted towards this limit.
928
929For example, it can be helpful during development to avoid an infinite number of requests.
930
931###### pagination.stackAllItems
932
933Type: `boolean`\
934Default: `true`
935
936Defines how the parameter `allItems` in [pagination.paginate](#pagination.paginate), [pagination.filter](#pagination.filter) and [pagination.shouldContinue](#pagination.shouldContinue) is managed. When set to `false`, the parameter `allItems` is always an empty array.
937
938This option can be helpful to save on memory usage when working with a large dataset.
939
940##### localAddress
941
942Type: `string`
943
944The IP address used to send the request from.
945
946### Advanced HTTPS API
947
948Note: If the request is not HTTPS, these options will be ignored.
949
950##### https.certificateAuthority
951
952Type: `string | Buffer | Array<string | Buffer>`
953
954Override the default Certificate Authorities ([from Mozilla](https://ccadb-public.secure.force.com/mozilla/IncludedCACertificateReport))
955
956```js
957// Single Certificate Authority
958got('https://example.com', {
959 https: {
960 certificateAuthority: fs.readFileSync('./my_ca.pem')
961 }
962});
963```
964
965##### https.key
966
967Type: `string | Buffer | Array<string | Buffer> | object[]`
968
969Private keys in [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) format.\
970[PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) allows the option of private keys being encrypted. Encrypted keys will be decrypted with `options.https.passphrase`.\
971Multiple keys with different passphrases can be provided as an array of `{pem: <string | Buffer>, passphrase: <string>}`
972
973##### https.certificate
974
975Type: `string | Buffer | (string | Buffer)[]`
976
977[Certificate chains](https://en.wikipedia.org/wiki/X.509#Certificate_chains_and_cross-certification) in [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) format.\
978One cert chain should be provided per private key (`options.https.key`).\
979When providing multiple cert chains, they do not have to be in the same order as their private keys in `options.https.key`.\
980If the intermediate certificates are not provided, the peer will not be able to validate the certificate, and the handshake will fail.
981
982##### https.passphrase
983
984Type: `string`
985
986The passphrase to decrypt the `options.https.key` (if different keys have different passphrases refer to `options.https.key` documentation).
987
988##### Examples for `https.key`, `https.certificate` and `https.passphrase`
989
990```js
991// Single key with certificate
992got('https://example.com', {
993 https: {
994 key: fs.readFileSync('./client_key.pem'),
995 certificate: fs.readFileSync('./client_cert.pem')
996 }
997});
998
999// Multiple keys with certificates (out of order)
1000got('https://example.com', {
1001 https: {
1002 key: [
1003 fs.readFileSync('./client_key1.pem'),
1004 fs.readFileSync('./client_key2.pem')
1005 ],
1006 certificate: [
1007 fs.readFileSync('./client_cert2.pem'),
1008 fs.readFileSync('./client_cert1.pem')
1009 ]
1010 }
1011});
1012
1013// Single key with passphrase
1014got('https://example.com', {
1015 https: {
1016 key: fs.readFileSync('./client_key.pem'),
1017 certificate: fs.readFileSync('./client_cert.pem'),
1018 passphrase: 'client_key_passphrase'
1019 }
1020});
1021
1022// Multiple keys with different passphrases
1023got('https://example.com', {
1024 https: {
1025 key: [
1026 {pem: fs.readFileSync('./client_key1.pem'), passphrase: 'passphrase1'},
1027 {pem: fs.readFileSync('./client_key2.pem'), passphrase: 'passphrase2'},
1028 ],
1029 certificate: [
1030 fs.readFileSync('./client_cert1.pem'),
1031 fs.readFileSync('./client_cert2.pem')
1032 ]
1033 }
1034});
1035```
1036
1037##### https.rejectUnauthorized
1038
1039Type: `boolean`\
1040Default: `true`
1041
1042If set to `false`, all invalid SSL certificates will be ignored and no error will be thrown.\
1043If set to `true`, it will throw an error whenever an invalid SSL certificate is detected.
1044
1045We strongly recommend to have this set to `true` for security reasons.
1046
1047```js
1048const got = require('got');
1049
1050(async () => {
1051 // Correct:
1052 await got('https://example.com', {
1053 https: {
1054 rejectUnauthorized: true
1055 }
1056 });
1057
1058 // You can disable it when developing an HTTPS app:
1059 await got('https://localhost', {
1060 https: {
1061 rejectUnauthorized: false
1062 }
1063 });
1064
1065 // Never do this:
1066 await got('https://example.com', {
1067 https: {
1068 rejectUnauthorized: false
1069 }
1070 });
1071```
1072
1073##### https.checkServerIdentity
1074
1075Type: `Function`\
1076Signature: `(hostname: string, certificate: DetailedPeerCertificate) => Error | undefined`\
1077Default: `tls.checkServerIdentity` (from the `tls` module)
1078
1079This function enable a custom check of the certificate.\
1080Note: In order to have the function called the certificate must not be `expired`, `self-signed` or with an `untrusted-root`.\
1081The function parameters are:
1082- `hostname`: The server hostname (used when connecting)
1083- `certificate`: The server certificate
1084
1085The function must return `undefined` if the check succeeded or an `Error` if it failed.
1086
1087```js
1088await got('https://example.com', {
1089 https: {
1090 checkServerIdentity: (hostname, certificate) => {
1091 if (hostname === 'example.com') {
1092 return; // Certificate OK
1093 }
1094
1095 return new Error('Invalid Hostname'); // Certificate NOT OK
1096 }
1097 }
1098});
1099```
1100
1101#### Response
1102
1103The response object will typically be a [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage), however, if returned from the cache it will be a [response-like object](https://github.com/lukechilds/responselike) which behaves in the same way.
1104
1105##### request
1106
1107Type: `object`
1108
1109**Note:** This is not a [http.ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest).
1110
1111- `options` - The Got options that were set on this request.
1112
1113##### body
1114
1115Type: `string | object | Buffer` *(Depending on `options.responseType`)*
1116
1117The result of the request.
1118
1119##### rawBody
1120
1121Type: `Buffer`
1122
1123The raw result of the request.
1124
1125##### url
1126
1127Type: `string`
1128
1129The request URL or the final URL after redirects.
1130
1131##### ip
1132
1133Type: `string`
1134
1135The remote IP address.
1136
1137**Note:** Not available when the response is cached. This is hopefully a temporary limitation, see [lukechilds/cacheable-request#86](https://github.com/lukechilds/cacheable-request/issues/86).
1138
1139##### requestUrl
1140
1141Type: `string`
1142
1143The original request URL.
1144
1145##### timings
1146
1147Type: `object`
1148
1149The object contains the following properties:
1150
1151- `start` - Time when the request started.
1152- `socket` - Time when a socket was assigned to the request.
1153- `lookup` - Time when the DNS lookup finished.
1154- `connect` - Time when the socket successfully connected.
1155- `secureConnect` - Time when the socket securely connected.
1156- `upload` - Time when the request finished uploading.
1157- `response` - Time when the request fired `response` event.
1158- `end` - Time when the response fired `end` event.
1159- `error` - Time when the request fired `error` event.
1160- `abort` - Time when the request fired `abort` event.
1161- `phases`
1162 - `wait` - `timings.socket - timings.start`
1163 - `dns` - `timings.lookup - timings.socket`
1164 - `tcp` - `timings.connect - timings.lookup`
1165 - `tls` - `timings.secureConnect - timings.connect`
1166 - `request` - `timings.upload - (timings.secureConnect || timings.connect)`
1167 - `firstByte` - `timings.response - timings.upload`
1168 - `download` - `timings.end - timings.response`
1169 - `total` - `(timings.end || timings.error || timings.abort) - timings.start`
1170
1171If something has not been measured yet, it will be `undefined`.
1172
1173**Note:** The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
1174
1175##### isFromCache
1176
1177Type: `boolean`
1178
1179Whether the response was retrieved from the cache.
1180
1181##### redirectUrls
1182
1183Type: `string[]`
1184
1185The redirect URLs.
1186
1187##### retryCount
1188
1189Type: `number`
1190
1191The number of times the request was retried.
1192
1193#### Streams
1194
1195**Note:** Progress events, redirect events and request/response events can also be used with promises.
1196
1197**Note:** To access `response.isFromCache` you need to use `got.stream(url, options).isFromCache`. The value will be undefined until the `response` event.
1198
1199#### got.stream(url, options?)
1200
1201Sets `options.isStream` to `true`.
1202
1203Returns a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex) with additional events:
1204
1205##### .on('request', request)
1206
1207`request` event to get the request object of the request.
1208
1209**Tip:** You can use `request` event to abort request:
1210
1211```js
1212got.stream('https://github.com')
1213 .on('request', request => setTimeout(() => request.destroy(), 50));
1214```
1215
1216##### .on('response', response)
1217
1218The `response` event to get the response object of the final request.
1219
1220##### .on('redirect', response, nextOptions)
1221
1222The `redirect` event to get the response object of a redirect. The second argument is options for the next request to the redirect location.
1223
1224##### .on('uploadProgress', progress)
1225##### .uploadProgress
1226##### .on('downloadProgress', progress)
1227##### .downloadProgress
1228
1229Progress events for uploading (sending a request) and downloading (receiving a response). The `progress` argument is an object like:
1230
1231```js
1232{
1233 percent: 0.1,
1234 transferred: 1024,
1235 total: 10240
1236}
1237```
1238
1239If the `content-length` header is missing, `total` will be `undefined`.
1240
1241```js
1242(async () => {
1243 const response = await got('https://sindresorhus.com')
1244 .on('downloadProgress', progress => {
1245 // Report download progress
1246 })
1247 .on('uploadProgress', progress => {
1248 // Report upload progress
1249 });
1250
1251 console.log(response);
1252})();
1253```
1254
1255##### .ip
1256
1257Type: `string`
1258
1259The remote IP address.
1260
1261##### .aborted
1262
1263Type: `boolean`
1264
1265Indicates whether the request has been aborted or not.
1266
1267##### .timings
1268
1269The same as `response.timings`.
1270
1271##### .isFromCache
1272
1273The same as `response.isFromCache`.
1274
1275##### .socket
1276
1277The same as `response.socket`.
1278
1279##### .on('error', error)
1280
1281The emitted `error` is an instance of [`RequestError`](#got.requesterror).
1282
1283#### Pagination
1284
1285#### got.paginate(url, options?)
1286#### got.paginate.each(url, options?)
1287
1288Returns an async iterator:
1289
1290```js
1291(async () => {
1292 const countLimit = 10;
1293
1294 const pagination = got.paginate('https://api.github.com/repos/sindresorhus/got/commits', {
1295 pagination: {countLimit}
1296 });
1297
1298 console.log(`Printing latest ${countLimit} Got commits (newest to oldest):`);
1299
1300 for await (const commitData of pagination) {
1301 console.log(commitData.commit.message);
1302 }
1303})();
1304```
1305
1306See [`options.pagination`](#pagination) for more pagination options.
1307
1308#### got.paginate.all(url, options?)
1309
1310Returns a Promise for an array of all results:
1311
1312```js
1313(async () => {
1314 const countLimit = 10;
1315
1316 const results = await got.paginate.all('https://api.github.com/repos/sindresorhus/got/commits', {
1317 pagination: {countLimit}
1318 });
1319
1320 console.log(`Printing latest ${countLimit} Got commits (newest to oldest):`);
1321 console.log(results);
1322})();
1323```
1324
1325See [`options.pagination`](#pagination) for more pagination options.
1326
1327#### got.get(url, options?)
1328#### got.post(url, options?)
1329#### got.put(url, options?)
1330#### got.patch(url, options?)
1331#### got.head(url, options?)
1332#### got.delete(url, options?)
1333
1334Sets [`options.method`](#method) to the method name and makes a request.
1335
1336### Instances
1337
1338#### got.extend(...options)
1339
1340Configure a new `got` instance with default `options`. The `options` are merged with the parent instance's `defaults.options` using [`got.mergeOptions`](#gotmergeoptionsparentoptions-newoptions). You can access the resolved options with the `.defaults` property on the instance.
1341
1342```js
1343const client = got.extend({
1344 prefixUrl: 'https://example.com',
1345 headers: {
1346 'x-unicorn': 'rainbow'
1347 }
1348});
1349
1350client.get('demo');
1351
1352/* HTTP Request =>
1353 * GET /demo HTTP/1.1
1354 * Host: example.com
1355 * x-unicorn: rainbow
1356 */
1357```
1358
1359```js
1360(async () => {
1361 const client = got.extend({
1362 prefixUrl: 'httpbin.org',
1363 headers: {
1364 'x-foo': 'bar'
1365 }
1366 });
1367 const {headers} = await client.get('headers').json();
1368 //=> headers['x-foo'] === 'bar'
1369
1370 const jsonClient = client.extend({
1371 responseType: 'json',
1372 resolveBodyOnly: true,
1373 headers: {
1374 'x-baz': 'qux'
1375 }
1376 });
1377 const {headers: headers2} = await jsonClient.get('headers');
1378 //=> headers2['x-foo'] === 'bar'
1379 //=> headers2['x-baz'] === 'qux'
1380})();
1381```
1382
1383Additionally, `got.extend()` accepts two properties from the `defaults` object: `mutableDefaults` and `handlers`. Example:
1384
1385```js
1386// You can now modify `mutableGot.defaults.options`.
1387const mutableGot = got.extend({mutableDefaults: true});
1388
1389const mergedHandlers = got.extend({
1390 handlers: [
1391 (options, next) => {
1392 delete options.headers.referer;
1393
1394 return next(options);
1395 }
1396 ]
1397});
1398```
1399
1400**Note:** Handlers can be asynchronous. The recommended approach is:
1401
1402```js
1403const handler = (options, next) => {
1404 if (options.isStream) {
1405 // It's a Stream
1406 return next(options);
1407 }
1408
1409 // It's a Promise
1410 return (async () => {
1411 try {
1412 const response = await next(options);
1413 response.yourOwnProperty = true;
1414 return response;
1415 } catch (error) {
1416 // Every error will be replaced by this one.
1417 // Before you receive any error here,
1418 // it will be passed to the `beforeError` hooks first.
1419 // Note: this one won't be passed to `beforeError` hook. It's final.
1420 throw new Error('Your very own error.');
1421 }
1422 })();
1423};
1424
1425const instance = got.extend({handlers: [handler]});
1426```
1427
1428#### got.extend(...options, ...instances, ...)
1429
1430Merges many instances into a single one:
1431- options are merged using [`got.mergeOptions()`](#gotmergeoptionsparentoptions-newoptions) (including hooks),
1432- handlers are stored in an array (you can access them through `instance.defaults.handlers`).
1433
1434```js
1435const a = {headers: {cat: 'meow'}};
1436const b = got.extend({
1437 options: {
1438 headers: {
1439 cow: 'moo'
1440 }
1441 }
1442});
1443
1444// The same as `got.extend(a).extend(b)`.
1445// Note `a` is options and `b` is an instance.
1446got.extend(a, b);
1447//=> {headers: {cat: 'meow', cow: 'moo'}}
1448```
1449
1450#### got.mergeOptions(parent, ...sources)
1451
1452Extends parent options. Avoid using [object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) as it doesn't work recursively:
1453
1454```js
1455const a = {headers: {cat: 'meow', wolf: ['bark', 'wrrr']}};
1456const b = {headers: {cow: 'moo', wolf: ['auuu']}};
1457
1458{...a, ...b} // => {headers: {cow: 'moo', wolf: ['auuu']}}
1459got.mergeOptions(a, b) // => {headers: {cat: 'meow', cow: 'moo', wolf: ['auuu']}}
1460```
1461
1462**Note:** Only Got options are merged! Custom user options should be defined via [`options.context`](#context).
1463
1464Options are deeply merged to a new object. The value of each key is determined as follows:
1465
1466- If the new property is not defined, the old value is used.
1467- If the new property is explicitly set to `undefined`:
1468 - If the parent property is a plain `object`, the parent value is deeply cloned.
1469 - Otherwise, `undefined` is used.
1470- If the parent value is an instance of `URLSearchParams`:
1471 - If the new value is a `string`, an `object` or an instance of `URLSearchParams`, a new `URLSearchParams` instance is created. The values are merged using [`urlSearchParams.append(key, value)`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/append). The keys defined in the new value override the keys defined in the parent value. Please note that `null` values point to an empty string and `undefined` values will exclude the entry.
1472 - Otherwise, the only available value is `undefined`.
1473- If the new property is a plain `object`:
1474 - If the parent property is a plain `object` too, both values are merged recursively into a new `object`.
1475 - Otherwise, only the new value is deeply cloned.
1476- If the new property is an `Array`, it overwrites the old one with a deep clone of the new property.
1477- Properties that are not enumerable, such as `context`, `body`, `json`, and `form`, will not be merged.
1478- Otherwise, the new value is assigned to the key.
1479
1480```js
1481const a = {json: {cat: 'meow'}};
1482const b = {json: {cow: 'moo'}};
1483
1484got.mergeOptions(a, b);
1485//=> {json: {cow: 'moo'}}
1486```
1487
1488#### got.defaults
1489
1490Type: `object`
1491
1492The Got defaults used in that instance.
1493
1494##### [options](#options)
1495
1496##### handlers
1497
1498Type: `Function[]`\
1499Default: `[]`
1500
1501An array of functions. You execute them directly by calling `got()`. They are some sort of "global hooks" - these functions are called first. The last handler (*it's hidden*) is either [`asPromise`](source/core/as-promise/index.ts) or [`asStream`](source/core/index.ts), depending on the `options.isStream` property.
1502
1503Each handler takes two arguments:
1504
1505###### [options](#options)
1506
1507###### next()
1508
1509Returns a `Promise` or a `Stream` depending on [`options.isStream`](#isstream).
1510
1511```js
1512const settings = {
1513 handlers: [
1514 (options, next) => {
1515 if (options.isStream) {
1516 // It's a Stream, so we can perform stream-specific actions on it
1517 return next(options)
1518 .on('request', request => {
1519 setTimeout(() => {
1520 request.abort();
1521 }, 50);
1522 });
1523 }
1524
1525 // It's a Promise
1526 return next(options);
1527 }
1528 ],
1529 options: got.mergeOptions(got.defaults.options, {
1530 responseType: 'json'
1531 })
1532};
1533
1534const jsonGot = got.extend(settings);
1535```
1536
1537##### mutableDefaults
1538
1539Type: `boolean`\
1540Default: `false`
1541
1542A read-only boolean describing whether the defaults are mutable or not. If set to `true`, you can [update headers over time](#hooksafterresponse), for example, update an access token when it expires.
1543
1544## Types
1545
1546Got exports some handy TypeScript types and interfaces. See the type definition for all the exported types.
1547
1548### Got
1549
1550TypeScript will automatically infer types for Got instances, but in case you want to define something like dependencies, you can import the available types directly from Got.
1551
1552```ts
1553import {GotRequestFunction} from 'got';
1554
1555interface Dependencies {
1556 readonly post: GotRequestFunction
1557}
1558```
1559
1560### Hooks
1561
1562When writing hooks, you can refer to their types to keep your interfaces consistent.
1563
1564```ts
1565import {BeforeRequestHook} from 'got';
1566
1567const addAccessToken = (accessToken: string): BeforeRequestHook => options => {
1568 options.path = `${options.path}?access_token=${accessToken}`;
1569}
1570```
1571
1572## Errors
1573
1574Each error contains an `options` property which are the options Got used to create a request - just to make debugging easier.\
1575Additionaly, the errors may have `request` (Got Stream) and `response` (Got Response) properties depending on which phase of the request failed.
1576
1577#### got.CacheError
1578
1579When a cache method fails, for example, if the database goes down or there's a filesystem error.
1580
1581#### got.RequestError
1582
1583When a request fails. Contains a `code` property with error class code, like `ECONNREFUSED`.
1584
1585#### got.ReadError
1586
1587When reading from response stream fails.
1588
1589#### got.ParseError
1590
1591When server response code is 2xx, and parsing body fails. Includes a `response` property.
1592
1593#### got.HTTPError
1594
1595When the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304. Includes a `response` property.
1596
1597#### got.MaxRedirectsError
1598
1599When the server redirects you more than ten times. Includes a `response` property.
1600
1601#### got.UnsupportedProtocolError
1602
1603When given an unsupported protocol.
1604
1605#### got.CancelError
1606
1607When the request is aborted with `.cancel()`.
1608
1609#### got.TimeoutError
1610
1611When the request is aborted due to a [timeout](#timeout). Includes an `event` and `timings` property.
1612
1613## Aborting the request
1614
1615The promise returned by Got has a [`.cancel()`](https://github.com/sindresorhus/p-cancelable) method which when called, aborts the request.
1616
1617```js
1618(async () => {
1619 const request = got(url, options);
1620
1621 // …
1622
1623 // In another part of the code
1624 if (something) {
1625 request.cancel();
1626 }
1627
1628 // …
1629
1630 try {
1631 await request;
1632 } catch (error) {
1633 if (request.isCanceled) { // Or `error instanceof got.CancelError`
1634 // Handle cancelation
1635 }
1636
1637 // Handle other errors
1638 }
1639})();
1640```
1641
1642When using hooks, simply throw an error to abort the request.
1643
1644```js
1645const got = require('got');
1646
1647(async () => {
1648 const request = got(url, {
1649 hooks: {
1650 beforeRequest: [
1651 () => {
1652 throw new Error('Oops. Request canceled.');
1653 }
1654 ]
1655 }
1656 });
1657
1658 try {
1659 await request;
1660 } catch (error) {
1661 // …
1662 }
1663})();
1664```
1665
1666To abort the Got Stream request, just call `stream.destroy()`.
1667
1668```js
1669const got = require('got');
1670
1671const stream = got.stream(url);
1672stream.destroy();
1673```
1674
1675<a name="cache-adapters"></a>
1676## Cache
1677
1678Got implements [RFC 7234](https://httpwg.org/specs/rfc7234.html) compliant HTTP caching which works out of the box in-memory and is easily pluggable with a wide range of storage adapters. Fresh cache entries are served directly from the cache, and stale cache entries are revalidated with `If-None-Match`/`If-Modified-Since` headers. You can read more about the underlying cache behavior in the [`cacheable-request` documentation](https://github.com/lukechilds/cacheable-request). For DNS cache, Got uses [`cacheable-lookup`](https://github.com/szmarczak/cacheable-lookup).
1679
1680You can use the JavaScript `Map` type as an in-memory cache:
1681
1682```js
1683const got = require('got');
1684
1685const map = new Map();
1686
1687(async () => {
1688 let response = await got('https://sindresorhus.com', {cache: map});
1689 console.log(response.isFromCache);
1690 //=> false
1691
1692 response = await got('https://sindresorhus.com', {cache: map});
1693 console.log(response.isFromCache);
1694 //=> true
1695})();
1696```
1697
1698Got uses [Keyv](https://github.com/lukechilds/keyv) internally to support a wide range of storage adapters. For something more scalable you could use an [official Keyv storage adapter](https://github.com/lukechilds/keyv#official-storage-adapters):
1699
1700```
1701$ npm install @keyv/redis
1702```
1703
1704```js
1705const got = require('got');
1706const KeyvRedis = require('@keyv/redis');
1707
1708const redis = new KeyvRedis('redis://user:pass@localhost:6379');
1709
1710got('https://sindresorhus.com', {cache: redis});
1711```
1712
1713Got supports anything that follows the Map API, so it's easy to write your own storage adapter or use a third-party solution.
1714
1715For example, the following are all valid storage adapters:
1716
1717```js
1718const storageAdapter = new Map();
1719// Or
1720const storageAdapter = require('./my-storage-adapter');
1721// Or
1722const QuickLRU = require('quick-lru');
1723const storageAdapter = new QuickLRU({maxSize: 1000});
1724
1725got('https://sindresorhus.com', {cache: storageAdapter});
1726```
1727
1728View the [Keyv docs](https://github.com/lukechilds/keyv) for more information on how to use storage adapters.
1729
1730## Proxies
1731
1732You can use the [`tunnel`](https://github.com/koichik/node-tunnel) package with the `agent` option to work with proxies:
1733
1734```js
1735const got = require('got');
1736const tunnel = require('tunnel');
1737
1738got('https://sindresorhus.com', {
1739 agent: {
1740 https: tunnel.httpOverHttp({
1741 proxy: {
1742 host: 'localhost'
1743 }
1744 })
1745 }
1746});
1747```
1748
1749Alternatively, use [`global-agent`](https://github.com/gajus/global-agent) to configure a global proxy for all HTTP/HTTPS traffic in your program.
1750
1751## Cookies
1752
1753You can use the [`tough-cookie`](https://github.com/salesforce/tough-cookie) package:
1754
1755```js
1756const {promisify} = require('util');
1757const got = require('got');
1758const {CookieJar} = require('tough-cookie');
1759
1760(async () => {
1761 const cookieJar = new CookieJar();
1762 const setCookie = promisify(cookieJar.setCookie.bind(cookieJar));
1763
1764 await setCookie('foo=bar', 'https://example.com');
1765 await got('https://example.com', {cookieJar});
1766})();
1767```
1768
1769## Form data
1770
1771You can use the [`form-data`](https://github.com/form-data/form-data) package to create POST request with form data:
1772
1773```js
1774const fs = require('fs');
1775const got = require('got');
1776const FormData = require('form-data');
1777
1778const form = new FormData();
1779
1780form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
1781
1782got.post('https://example.com', {
1783 body: form
1784});
1785```
1786
1787## OAuth
1788
1789You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) package to create a signed OAuth request:
1790
1791```js
1792const got = require('got');
1793const crypto = require('crypto');
1794const OAuth = require('oauth-1.0a');
1795
1796const oauth = OAuth({
1797 consumer: {
1798 key: process.env.CONSUMER_KEY,
1799 secret: process.env.CONSUMER_SECRET
1800 },
1801 signature_method: 'HMAC-SHA1',
1802 hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
1803});
1804
1805const token = {
1806 key: process.env.ACCESS_TOKEN,
1807 secret: process.env.ACCESS_TOKEN_SECRET
1808};
1809
1810const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
1811
1812got(url, {
1813 headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
1814 responseType: 'json'
1815});
1816```
1817
1818## Unix Domain Sockets
1819
1820Requests can also be sent via [unix domain sockets](http://serverfault.com/questions/124517/whats-the-difference-between-unix-socket-and-tcp-ip-socket). Use the following URL scheme: `PROTOCOL://unix:SOCKET:PATH`.
1821
1822- `PROTOCOL` - `http` or `https` *(optional)*
1823- `SOCKET` - Absolute path to a unix domain socket, for example: `/var/run/docker.sock`
1824- `PATH` - Request path, for example: `/v2/keys`
1825
1826```js
1827const got = require('got');
1828
1829got('http://unix:/var/run/docker.sock:/containers/json');
1830
1831// Or without protocol (HTTP by default)
1832got('unix:/var/run/docker.sock:/containers/json');
1833```
1834
1835## AWS
1836
1837Requests to AWS services need to have their headers signed. This can be accomplished by using the [`aws4`](https://www.npmjs.com/package/aws4) package. This is an example for querying an ["API Gateway"](https://docs.aws.amazon.com/apigateway/api-reference/signing-requests/) with a signed request.
1838
1839```js
1840const got = require('got');
1841const AWS = require('aws-sdk');
1842const aws4 = require('aws4');
1843
1844const chain = new AWS.CredentialProviderChain();
1845
1846// Create a Got instance to use relative paths and signed requests
1847const awsClient = got.extend({
1848 prefixUrl: 'https://<api-id>.execute-api.<api-region>.amazonaws.com/<stage>/',
1849 hooks: {
1850 beforeRequest: [
1851 async options => {
1852 const credentials = await chain.resolvePromise();
1853 aws4.sign(options, credentials);
1854 }
1855 ]
1856 }
1857});
1858
1859const response = await awsClient('endpoint/path', {
1860 // Request-specific options
1861});
1862```
1863
1864## Testing
1865
1866You can test your requests by using the [`nock`](https://github.com/node-nock/nock) package to mock an endpoint:
1867
1868```js
1869const got = require('got');
1870const nock = require('nock');
1871
1872nock('https://sindresorhus.com')
1873 .get('/')
1874 .reply(200, 'Hello world!');
1875
1876(async () => {
1877 const response = await got('https://sindresorhus.com');
1878 console.log(response.body);
1879 //=> 'Hello world!'
1880})();
1881```
1882
1883For real integration testing we recommend using [`ava`](https://github.com/avajs/ava) with [`create-test-server`](https://github.com/lukechilds/create-test-server). We're using a macro so we don't have to `server.listen()` and `server.close()` every test. Take a look at one of our tests:
1884
1885```js
1886test('retry function gets iteration count', withServer, async (t, server, got) => {
1887 let knocks = 0;
1888 server.get('/', (request, response) => {
1889 if (knocks++ === 1) {
1890 response.end('who`s there?');
1891 }
1892 });
1893
1894 await got({
1895 retry: {
1896 calculateDelay: ({attemptCount}) => {
1897 t.true(is.number(attemptCount));
1898 return attemptCount < 2 ? 1 : 0;
1899 }
1900 }
1901 });
1902});
1903```
1904
1905## Tips
1906
1907### JSON mode
1908
1909To pass an object as the body, you need to use the `json` option. It will be stringified using `JSON.stringify`. Example:
1910
1911```js
1912const got = require('got');
1913
1914(async () => {
1915 const {body} = await got.post('https://httpbin.org/anything', {
1916 json: {
1917 hello: 'world'
1918 },
1919 responseType: 'json'
1920 });
1921
1922 console.log(body.data);
1923 //=> '{"hello":"world"}'
1924})();
1925```
1926
1927To receive a JSON body you can either set `responseType` option to `json` or use `promise.json()`. Example:
1928
1929```js
1930const got = require('got');
1931
1932(async () => {
1933 const body = await got.post('https://httpbin.org/anything', {
1934 json: {
1935 hello: 'world'
1936 }
1937 }).json();
1938
1939 console.log(body);
1940 //=> {…}
1941})();
1942```
1943
1944### User Agent
1945
1946It's a good idea to set the `'user-agent'` header so the provider can more easily see how their resource is used. By default, it's the URL to this repo. You can omit this header by setting it to `undefined`.
1947
1948```js
1949const got = require('got');
1950const pkg = require('./package.json');
1951
1952got('https://sindresorhus.com', {
1953 headers: {
1954 'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
1955 }
1956});
1957
1958got('https://sindresorhus.com', {
1959 headers: {
1960 'user-agent': undefined
1961 }
1962});
1963```
1964
1965### 304 Responses
1966
1967Bear in mind; if you send an `if-modified-since` header and receive a `304 Not Modified` response, the body will be empty. It's your responsibility to cache and retrieve the body contents.
1968
1969### Custom endpoints
1970
1971Use `got.extend()` to make it nicer to work with REST APIs. Especially if you use the `prefixUrl` option.
1972
1973```js
1974const got = require('got');
1975const pkg = require('./package.json');
1976
1977const custom = got.extend({
1978 prefixUrl: 'example.com',
1979 responseType: 'json',
1980 headers: {
1981 'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
1982 }
1983});
1984
1985// Use `custom` exactly how you use `got`
1986(async () => {
1987 const list = await custom('v1/users/list');
1988})();
1989```
1990
1991## FAQ
1992
1993### Why yet another HTTP client?
1994
1995Got was created because the popular [`request`](https://github.com/request/request) package is bloated: [![Install size](https://packagephobia.now.sh/badge?p=request)](https://packagephobia.now.sh/result?p=request)\
1996Furthermore, Got is fully written in TypeScript and actively maintained.
1997
1998### Electron support has been removed
1999
2000The Electron `net` module is not consistent with the Node.js `http` module. See [#899](https://github.com/sindresorhus/got/issues/899) for more info.
2001
2002## Comparison
2003
2004| | `got` | [`request`][r0] | [`node-fetch`][n0] | [`ky`][k0] | [`axios`][a0] | [`superagent`][s0] |
2005|-----------------------|:------------------:|:------------------:|:--------------------:|:------------------------:|:------------------:|:----------------------:|
2006| HTTP/2 support | :sparkle: | :x: | :x: | :x: | :x: | :heavy_check_mark:\*\* |
2007| Browser support | :x: | :x: | :heavy_check_mark:\* | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2008| Promise API | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2009| Stream API | :heavy_check_mark: | :heavy_check_mark: | Node.js only | :x: | :x: | :heavy_check_mark: |
2010| Pagination API | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2011| Request cancelation | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2012| RFC compliant caching | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2013| Cookies (out-of-box) | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
2014| Follows redirects | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2015| Retries on failure | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: |
2016| Progress events | :heavy_check_mark: | :x: | :x: | :heavy_check_mark:\*\*\* | Browser only | :heavy_check_mark: |
2017| Handles gzip/deflate | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2018| Advanced timeouts | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2019| Timings | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
2020| Errors with metadata | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2021| JSON mode | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2022| Custom defaults | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2023| Composable | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: |
2024| Hooks | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2025| Issues open | [![][gio]][g1] | [![][rio]][r1] | [![][nio]][n1] | [![][kio]][k1] | [![][aio]][a1] | [![][sio]][s1] |
2026| Issues closed | [![][gic]][g2] | [![][ric]][r2] | [![][nic]][n2] | [![][kic]][k2] | [![][aic]][a2] | [![][sic]][s2] |
2027| Downloads | [![][gd]][g3] | [![][rd]][r3] | [![][nd]][n3] | [![][kd]][k3] | [![][ad]][a3] | [![][sd]][s3] |
2028| Coverage | [![][gc]][g4] | [![][rc]][r4] | [![][nc]][n4] | [![][kc]][k4] | [![][ac]][a4] | [![][sc]][s4] |
2029| Build | [![][gb]][g5] | [![][rb]][r5] | [![][nb]][n5] | [![][kb]][k5] | [![][ab]][a5] | [![][sb]][s5] |
2030| Bugs | [![][gbg]][g6] | [![][rbg]][r6] | [![][nbg]][n6] | [![][kbg]][k6] | [![][abg]][a6] | [![][sbg]][s6] |
2031| Dependents | [![][gdp]][g7] | [![][rdp]][r7] | [![][ndp]][n7] | [![][kdp]][k7] | [![][adp]][a7] | [![][sdp]][s7] |
2032| Install size | [![][gis]][g8] | [![][ris]][r8] | [![][nis]][n8] | [![][kis]][k8] | [![][ais]][a8] | [![][sis]][s8] |
2033
2034\* It's almost API compatible with the browser `fetch` API.\
2035\*\* Need to switch the protocol manually. Doesn't accept PUSH streams and doesn't reuse HTTP/2 sessions.\
2036\*\*\* Currently, only `DownloadProgress` event is supported, `UploadProgress` event is not supported.\
2037:sparkle: Almost-stable feature, but the API may change. Don't hestitate to try it out!\
2038:grey_question: Feature in early stage of development. Very experimental.
2039
2040<!-- GITHUB -->
2041[k0]: https://github.com/sindresorhus/ky
2042[r0]: https://github.com/request/request
2043[n0]: https://github.com/node-fetch/node-fetch
2044[a0]: https://github.com/axios/axios
2045[s0]: https://github.com/visionmedia/superagent
2046
2047<!-- ISSUES OPEN -->
2048[gio]: https://badgen.net/github/open-issues/sindresorhus/got?label
2049[kio]: https://badgen.net/github/open-issues/sindresorhus/ky?label
2050[rio]: https://badgen.net/github/open-issues/request/request?label
2051[nio]: https://badgen.net/github/open-issues/bitinn/node-fetch?label
2052[aio]: https://badgen.net/github/open-issues/axios/axios?label
2053[sio]: https://badgen.net/github/open-issues/visionmedia/superagent?label
2054
2055[g1]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2056[k1]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2057[r1]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2058[n1]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2059[a1]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2060[s1]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2061
2062<!-- ISSUES CLOSED -->
2063[gic]: https://badgen.net/github/closed-issues/sindresorhus/got?label
2064[kic]: https://badgen.net/github/closed-issues/sindresorhus/ky?label
2065[ric]: https://badgen.net/github/closed-issues/request/request?label
2066[nic]: https://badgen.net/github/closed-issues/bitinn/node-fetch?label
2067[aic]: https://badgen.net/github/closed-issues/axios/axios?label
2068[sic]: https://badgen.net/github/closed-issues/visionmedia/superagent?label
2069
2070[g2]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2071[k2]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2072[r2]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2073[n2]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2074[a2]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2075[s2]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2076
2077<!-- DOWNLOADS -->
2078[gd]: https://badgen.net/npm/dm/got?label
2079[kd]: https://badgen.net/npm/dm/ky?label
2080[rd]: https://badgen.net/npm/dm/request?label
2081[nd]: https://badgen.net/npm/dm/node-fetch?label
2082[ad]: https://badgen.net/npm/dm/axios?label
2083[sd]: https://badgen.net/npm/dm/superagent?label
2084
2085[g3]: https://www.npmjs.com/package/got
2086[k3]: https://www.npmjs.com/package/ky
2087[r3]: https://www.npmjs.com/package/request
2088[n3]: https://www.npmjs.com/package/node-fetch
2089[a3]: https://www.npmjs.com/package/axios
2090[s3]: https://www.npmjs.com/package/superagent
2091
2092<!-- COVERAGE -->
2093[gc]: https://badgen.net/coveralls/c/github/sindresorhus/got?label
2094[kc]: https://badgen.net/codecov/c/github/sindresorhus/ky?label
2095[rc]: https://badgen.net/coveralls/c/github/request/request?label
2096[nc]: https://badgen.net/coveralls/c/github/bitinn/node-fetch?label
2097[ac]: https://badgen.net/coveralls/c/github/mzabriskie/axios?label
2098[sc]: https://badgen.net/codecov/c/github/visionmedia/superagent?label
2099
2100[g4]: https://coveralls.io/github/sindresorhus/got
2101[k4]: https://codecov.io/gh/sindresorhus/ky
2102[r4]: https://coveralls.io/github/request/request
2103[n4]: https://coveralls.io/github/bitinn/node-fetch
2104[a4]: https://coveralls.io/github/mzabriskie/axios
2105[s4]: https://codecov.io/gh/visionmedia/superagent
2106
2107<!-- BUILD -->
2108[gb]: https://badgen.net/travis/sindresorhus/got?label
2109[kb]: https://badgen.net/travis/sindresorhus/ky?label
2110[rb]: https://badgen.net/travis/request/request?label
2111[nb]: https://badgen.net/travis/bitinn/node-fetch?label
2112[ab]: https://badgen.net/travis/axios/axios?label
2113[sb]: https://badgen.net/travis/visionmedia/superagent?label
2114
2115[g5]: https://travis-ci.org/sindresorhus/got
2116[k5]: https://travis-ci.org/sindresorhus/ky
2117[r5]: https://travis-ci.org/request/request
2118[n5]: https://travis-ci.org/bitinn/node-fetch
2119[a5]: https://travis-ci.org/axios/axios
2120[s5]: https://travis-ci.org/visionmedia/superagent
2121
2122<!-- BUGS -->
2123[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
2124[kbg]: https://badgen.net/github/label-issues/sindresorhus/ky/bug/open?label
2125[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open?label
2126[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open?label
2127[abg]: https://badgen.net/github/label-issues/axios/axios/type:confirmed%20bug/open?label
2128[sbg]: https://badgen.net/github/label-issues/visionmedia/superagent/Bug/open?label
2129
2130[g6]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2131[k6]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2132[r6]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A"Needs+investigation"
2133[n6]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2134[a6]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22type%3Aconfirmed+bug%22
2135[s6]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3ABug
2136
2137<!-- DEPENDENTS -->
2138[gdp]: https://badgen.net/npm/dependents/got?label
2139[kdp]: https://badgen.net/npm/dependents/ky?label
2140[rdp]: https://badgen.net/npm/dependents/request?label
2141[ndp]: https://badgen.net/npm/dependents/node-fetch?label
2142[adp]: https://badgen.net/npm/dependents/axios?label
2143[sdp]: https://badgen.net/npm/dependents/superagent?label
2144
2145[g7]: https://www.npmjs.com/package/got?activeTab=dependents
2146[k7]: https://www.npmjs.com/package/ky?activeTab=dependents
2147[r7]: https://www.npmjs.com/package/request?activeTab=dependents
2148[n7]: https://www.npmjs.com/package/node-fetch?activeTab=dependents
2149[a7]: https://www.npmjs.com/package/axios?activeTab=dependents
2150[s7]: https://www.npmjs.com/package/visionmedia?activeTab=dependents
2151
2152<!-- INSTALL SIZE -->
2153[gis]: https://badgen.net/packagephobia/install/got?label
2154[kis]: https://badgen.net/packagephobia/install/ky?label
2155[ris]: https://badgen.net/packagephobia/install/request?label
2156[nis]: https://badgen.net/packagephobia/install/node-fetch?label
2157[ais]: https://badgen.net/packagephobia/install/axios?label
2158[sis]: https://badgen.net/packagephobia/install/superagent?label
2159
2160[g8]: https://packagephobia.now.sh/result?p=got
2161[k8]: https://packagephobia.now.sh/result?p=ky
2162[r8]: https://packagephobia.now.sh/result?p=request
2163[n8]: https://packagephobia.now.sh/result?p=node-fetch
2164[a8]: https://packagephobia.now.sh/result?p=axios
2165[s8]: https://packagephobia.now.sh/result?p=superagent
2166
2167[Click here][InstallSizeOfTheDependencies] to see the install size of the Got dependencies.
2168
2169[InstallSizeOfTheDependencies]: https://packagephobia.now.sh/result?p=@sindresorhus/is@1.0.0,@szmarczak/http-timer@3.1.0,@types/cacheable-request@6.0.1,cacheable-lookup@0.2.1,cacheable-request@7.0.0,decompress-response@5.0.0,duplexer3@0.1.4,get-stream@5.0.0,lowercase-keys@2.0.0,mimic-response@2.0.0,p-cancelable@2.0.0,responselike@2.0.0,to-readable-stream@2.0.0,type-fest@0.8.0
2170
2171## Related
2172
2173- [gh-got](https://github.com/sindresorhus/gh-got) - Got convenience wrapper to interact with the GitHub API
2174- [gl-got](https://github.com/singapore/gl-got) - Got convenience wrapper to interact with the GitLab API
2175- [travis-got](https://github.com/samverschueren/travis-got) - Got convenience wrapper to interact with the Travis API
2176- [graphql-got](https://github.com/kevva/graphql-got) - Got convenience wrapper to interact with GraphQL
2177- [GotQL](https://github.com/khaosdoctor/gotql) - Got convenience wrapper to interact with GraphQL using JSON-parsed queries instead of strings
2178- [got-fetch](https://github.com/alexghr/got-fetch) - Got with a `fetch` interface
2179
2180## Maintainers
2181
2182[![Sindre Sorhus](https://github.com/sindresorhus.png?size=100)](https://sindresorhus.com) | [![Szymon Marczak](https://github.com/szmarczak.png?size=100)](https://github.com/szmarczak)
2183---|---
2184[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak)
2185
2186###### Former
2187
2188- [Vsevolod Strukchinsky](https://github.com/floatdrop)
2189- [Alexander Tesfamichael](https://github.com/alextes)
2190- [Brandon Smith](https://github.com/brandon93s)
2191- [Luke Childs](https://github.com/lukechilds)
2192
2193## For enterprise
2194
2195Available as part of the Tidelift Subscription.
2196
2197The maintainers of `got` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-got?utm_source=npm-got&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)