UNPKG

76.6 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.RequestError
1578
1579When a request fails. Contains a `code` property with error class code, like `ECONNREFUSED`. Note that all other types of errors listed below are subclasses of this one, with the exception of `CancelError`.
1580
1581#### got.CacheError
1582
1583When a cache method fails, for example, if the database goes down or there's a filesystem error.
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.UploadError
1594
1595When the request body is a stream and an error occurs while reading from that stream.
1596
1597#### got.HTTPError
1598
1599When the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304. Includes a `response` property.
1600
1601#### got.MaxRedirectsError
1602
1603When the server redirects you more than ten times. Includes a `response` property.
1604
1605#### got.UnsupportedProtocolError
1606
1607When given an unsupported protocol.
1608
1609#### got.TimeoutError
1610
1611When the request is aborted due to a [timeout](#timeout). Includes an `event` and `timings` property.
1612
1613#### got.CancelError
1614
1615When the request is aborted with `.cancel()`. This type is not a subclass of `RequestError` as it is re-exported from the `p-cancelable` package.
1616
1617## Aborting the request
1618
1619The promise returned by Got has a [`.cancel()`](https://github.com/sindresorhus/p-cancelable) method which when called, aborts the request.
1620
1621```js
1622(async () => {
1623 const request = got(url, options);
1624
1625 // …
1626
1627 // In another part of the code
1628 if (something) {
1629 request.cancel();
1630 }
1631
1632 // …
1633
1634 try {
1635 await request;
1636 } catch (error) {
1637 if (request.isCanceled) { // Or `error instanceof got.CancelError`
1638 // Handle cancelation
1639 }
1640
1641 // Handle other errors
1642 }
1643})();
1644```
1645
1646When using hooks, simply throw an error to abort the request.
1647
1648```js
1649const got = require('got');
1650
1651(async () => {
1652 const request = got(url, {
1653 hooks: {
1654 beforeRequest: [
1655 () => {
1656 throw new Error('Oops. Request canceled.');
1657 }
1658 ]
1659 }
1660 });
1661
1662 try {
1663 await request;
1664 } catch (error) {
1665 // …
1666 }
1667})();
1668```
1669
1670To abort the Got Stream request, just call `stream.destroy()`.
1671
1672```js
1673const got = require('got');
1674
1675const stream = got.stream(url);
1676stream.destroy();
1677```
1678
1679<a name="cache-adapters"></a>
1680## Cache
1681
1682Got 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).
1683
1684You can use the JavaScript `Map` type as an in-memory cache:
1685
1686```js
1687const got = require('got');
1688
1689const map = new Map();
1690
1691(async () => {
1692 let response = await got('https://sindresorhus.com', {cache: map});
1693 console.log(response.isFromCache);
1694 //=> false
1695
1696 response = await got('https://sindresorhus.com', {cache: map});
1697 console.log(response.isFromCache);
1698 //=> true
1699})();
1700```
1701
1702Got 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):
1703
1704```
1705$ npm install @keyv/redis
1706```
1707
1708```js
1709const got = require('got');
1710const KeyvRedis = require('@keyv/redis');
1711
1712const redis = new KeyvRedis('redis://user:pass@localhost:6379');
1713
1714got('https://sindresorhus.com', {cache: redis});
1715```
1716
1717Got supports anything that follows the Map API, so it's easy to write your own storage adapter or use a third-party solution.
1718
1719For example, the following are all valid storage adapters:
1720
1721```js
1722const storageAdapter = new Map();
1723// Or
1724const storageAdapter = require('./my-storage-adapter');
1725// Or
1726const QuickLRU = require('quick-lru');
1727const storageAdapter = new QuickLRU({maxSize: 1000});
1728
1729got('https://sindresorhus.com', {cache: storageAdapter});
1730```
1731
1732View the [Keyv docs](https://github.com/lukechilds/keyv) for more information on how to use storage adapters.
1733
1734## Proxies
1735
1736You can use the [`tunnel`](https://github.com/koichik/node-tunnel) package with the `agent` option to work with proxies:
1737
1738```js
1739const got = require('got');
1740const tunnel = require('tunnel');
1741
1742got('https://sindresorhus.com', {
1743 agent: {
1744 https: tunnel.httpsOverHttp({
1745 proxy: {
1746 host: 'localhost'
1747 }
1748 })
1749 }
1750});
1751```
1752
1753Alternatively, use [`global-agent`](https://github.com/gajus/global-agent) to configure a global proxy for all HTTP/HTTPS traffic in your program.
1754
1755Read the [`http2-wrapper`](https://github.com/szmarczak/http2-wrapper/#proxy-support) docs to learn about proxying for HTTP/2.
1756
1757## Cookies
1758
1759You can use the [`tough-cookie`](https://github.com/salesforce/tough-cookie) package:
1760
1761```js
1762const {promisify} = require('util');
1763const got = require('got');
1764const {CookieJar} = require('tough-cookie');
1765
1766(async () => {
1767 const cookieJar = new CookieJar();
1768 const setCookie = promisify(cookieJar.setCookie.bind(cookieJar));
1769
1770 await setCookie('foo=bar', 'https://example.com');
1771 await got('https://example.com', {cookieJar});
1772})();
1773```
1774
1775## Form data
1776
1777You can use the [`form-data`](https://github.com/form-data/form-data) package to create POST request with form data:
1778
1779```js
1780const fs = require('fs');
1781const got = require('got');
1782const FormData = require('form-data');
1783
1784const form = new FormData();
1785
1786form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
1787
1788got.post('https://example.com', {
1789 body: form
1790});
1791```
1792
1793## OAuth
1794
1795You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) package to create a signed OAuth request:
1796
1797```js
1798const got = require('got');
1799const crypto = require('crypto');
1800const OAuth = require('oauth-1.0a');
1801
1802const oauth = OAuth({
1803 consumer: {
1804 key: process.env.CONSUMER_KEY,
1805 secret: process.env.CONSUMER_SECRET
1806 },
1807 signature_method: 'HMAC-SHA1',
1808 hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
1809});
1810
1811const token = {
1812 key: process.env.ACCESS_TOKEN,
1813 secret: process.env.ACCESS_TOKEN_SECRET
1814};
1815
1816const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
1817
1818got(url, {
1819 headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
1820 responseType: 'json'
1821});
1822```
1823
1824## Unix Domain Sockets
1825
1826Requests 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`.
1827
1828- `PROTOCOL` - `http` or `https` *(optional)*
1829- `SOCKET` - Absolute path to a unix domain socket, for example: `/var/run/docker.sock`
1830- `PATH` - Request path, for example: `/v2/keys`
1831
1832```js
1833const got = require('got');
1834
1835got('http://unix:/var/run/docker.sock:/containers/json');
1836
1837// Or without protocol (HTTP by default)
1838got('unix:/var/run/docker.sock:/containers/json');
1839```
1840
1841## AWS
1842
1843Requests 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.
1844
1845```js
1846const got = require('got');
1847const AWS = require('aws-sdk');
1848const aws4 = require('aws4');
1849
1850const chain = new AWS.CredentialProviderChain();
1851
1852// Create a Got instance to use relative paths and signed requests
1853const awsClient = got.extend({
1854 prefixUrl: 'https://<api-id>.execute-api.<api-region>.amazonaws.com/<stage>/',
1855 hooks: {
1856 beforeRequest: [
1857 async options => {
1858 const credentials = await chain.resolvePromise();
1859 aws4.sign(options, credentials);
1860 }
1861 ]
1862 }
1863});
1864
1865const response = await awsClient('endpoint/path', {
1866 // Request-specific options
1867});
1868```
1869
1870## Testing
1871
1872You can test your requests by using the [`nock`](https://github.com/node-nock/nock) package to mock an endpoint:
1873
1874```js
1875const got = require('got');
1876const nock = require('nock');
1877
1878nock('https://sindresorhus.com')
1879 .get('/')
1880 .reply(200, 'Hello world!');
1881
1882(async () => {
1883 const response = await got('https://sindresorhus.com');
1884 console.log(response.body);
1885 //=> 'Hello world!'
1886})();
1887```
1888
1889For 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:
1890
1891```js
1892test('retry function gets iteration count', withServer, async (t, server, got) => {
1893 let knocks = 0;
1894 server.get('/', (request, response) => {
1895 if (knocks++ === 1) {
1896 response.end('who`s there?');
1897 }
1898 });
1899
1900 await got({
1901 retry: {
1902 calculateDelay: ({attemptCount}) => {
1903 t.true(is.number(attemptCount));
1904 return attemptCount < 2 ? 1 : 0;
1905 }
1906 }
1907 });
1908});
1909```
1910
1911## Tips
1912
1913### JSON mode
1914
1915To pass an object as the body, you need to use the `json` option. It will be stringified using `JSON.stringify`. Example:
1916
1917```js
1918const got = require('got');
1919
1920(async () => {
1921 const {body} = await got.post('https://httpbin.org/anything', {
1922 json: {
1923 hello: 'world'
1924 },
1925 responseType: 'json'
1926 });
1927
1928 console.log(body.data);
1929 //=> '{"hello":"world"}'
1930})();
1931```
1932
1933To receive a JSON body you can either set `responseType` option to `json` or use `promise.json()`. Example:
1934
1935```js
1936const got = require('got');
1937
1938(async () => {
1939 const body = await got.post('https://httpbin.org/anything', {
1940 json: {
1941 hello: 'world'
1942 }
1943 }).json();
1944
1945 console.log(body);
1946 //=> {…}
1947})();
1948```
1949
1950### User Agent
1951
1952It'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`.
1953
1954```js
1955const got = require('got');
1956const pkg = require('./package.json');
1957
1958got('https://sindresorhus.com', {
1959 headers: {
1960 'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
1961 }
1962});
1963
1964got('https://sindresorhus.com', {
1965 headers: {
1966 'user-agent': undefined
1967 }
1968});
1969```
1970
1971### 304 Responses
1972
1973Bear 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.
1974
1975### Custom endpoints
1976
1977Use `got.extend()` to make it nicer to work with REST APIs. Especially if you use the `prefixUrl` option.
1978
1979```js
1980const got = require('got');
1981const pkg = require('./package.json');
1982
1983const custom = got.extend({
1984 prefixUrl: 'example.com',
1985 responseType: 'json',
1986 headers: {
1987 'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
1988 }
1989});
1990
1991// Use `custom` exactly how you use `got`
1992(async () => {
1993 const list = await custom('v1/users/list');
1994})();
1995```
1996
1997## FAQ
1998
1999### Why yet another HTTP client?
2000
2001Got 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)\
2002Furthermore, Got is fully written in TypeScript and actively maintained.
2003
2004### Electron support has been removed
2005
2006The Electron `net` module is not consistent with the Node.js `http` module. See [#899](https://github.com/sindresorhus/got/issues/899) for more info.
2007
2008## Comparison
2009
2010| | `got` | [`request`][r0] | [`node-fetch`][n0] | [`ky`][k0] | [`axios`][a0] | [`superagent`][s0] |
2011|-----------------------|:------------------:|:------------------:|:--------------------:|:------------------------:|:------------------:|:----------------------:|
2012| HTTP/2 support | :sparkle: | :x: | :x: | :x: | :x: | :heavy_check_mark:\*\* |
2013| Browser support | :x: | :x: | :heavy_check_mark:\* | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2014| Promise API | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2015| Stream API | :heavy_check_mark: | :heavy_check_mark: | Node.js only | :x: | :x: | :heavy_check_mark: |
2016| Pagination API | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2017| Request cancelation | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2018| RFC compliant caching | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2019| Cookies (out-of-box) | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
2020| Follows redirects | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2021| Retries on failure | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: |
2022| Progress events | :heavy_check_mark: | :x: | :x: | :heavy_check_mark:\*\*\* | Browser only | :heavy_check_mark: |
2023| Handles gzip/deflate | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2024| Advanced timeouts | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2025| Timings | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
2026| Errors with metadata | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2027| JSON mode | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2028| Custom defaults | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2029| Composable | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: |
2030| Hooks | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2031| Issues open | [![][gio]][g1] | [![][rio]][r1] | [![][nio]][n1] | [![][kio]][k1] | [![][aio]][a1] | [![][sio]][s1] |
2032| Issues closed | [![][gic]][g2] | [![][ric]][r2] | [![][nic]][n2] | [![][kic]][k2] | [![][aic]][a2] | [![][sic]][s2] |
2033| Downloads | [![][gd]][g3] | [![][rd]][r3] | [![][nd]][n3] | [![][kd]][k3] | [![][ad]][a3] | [![][sd]][s3] |
2034| Coverage | [![][gc]][g4] | [![][rc]][r4] | [![][nc]][n4] | [![][kc]][k4] | [![][ac]][a4] | [![][sc]][s4] |
2035| Build | [![][gb]][g5] | [![][rb]][r5] | [![][nb]][n5] | [![][kb]][k5] | [![][ab]][a5] | [![][sb]][s5] |
2036| Bugs | [![][gbg]][g6] | [![][rbg]][r6] | [![][nbg]][n6] | [![][kbg]][k6] | [![][abg]][a6] | [![][sbg]][s6] |
2037| Dependents | [![][gdp]][g7] | [![][rdp]][r7] | [![][ndp]][n7] | [![][kdp]][k7] | [![][adp]][a7] | [![][sdp]][s7] |
2038| Install size | [![][gis]][g8] | [![][ris]][r8] | [![][nis]][n8] | [![][kis]][k8] | [![][ais]][a8] | [![][sis]][s8] |
2039| GitHub stars | [![][gs]][g9] | [![][rs]][r9] | [![][ns]][n9] | [![][ks]][k9] | [![][as]][a9] | [![][ss]][s9] |
2040| TypeScript support | [![][gts]][g10] | [![][rts]][r10] | [![][nts]][n10] | [![][kts]][k10] | [![][ats]][a10] | [![][sts]][s11] |
2041| Last commit | [![][glc]][g11] | [![][rlc]][r11] | [![][nlc]][n11] | [![][klc]][k11] | [![][alc]][a11] | [![][slc]][s11] |
2042
2043\* It's almost API compatible with the browser `fetch` API.\
2044\*\* Need to switch the protocol manually. Doesn't accept PUSH streams and doesn't reuse HTTP/2 sessions.\
2045\*\*\* Currently, only `DownloadProgress` event is supported, `UploadProgress` event is not supported.\
2046:sparkle: Almost-stable feature, but the API may change. Don't hestitate to try it out!\
2047:grey_question: Feature in early stage of development. Very experimental.
2048
2049<!-- GITHUB -->
2050[k0]: https://github.com/sindresorhus/ky
2051[r0]: https://github.com/request/request
2052[n0]: https://github.com/node-fetch/node-fetch
2053[a0]: https://github.com/axios/axios
2054[s0]: https://github.com/visionmedia/superagent
2055
2056<!-- ISSUES OPEN -->
2057[gio]: https://badgen.net/github/open-issues/sindresorhus/got?label
2058[kio]: https://badgen.net/github/open-issues/sindresorhus/ky?label
2059[rio]: https://badgen.net/github/open-issues/request/request?label
2060[nio]: https://badgen.net/github/open-issues/bitinn/node-fetch?label
2061[aio]: https://badgen.net/github/open-issues/axios/axios?label
2062[sio]: https://badgen.net/github/open-issues/visionmedia/superagent?label
2063
2064[g1]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2065[k1]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2066[r1]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2067[n1]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2068[a1]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2069[s1]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2070
2071<!-- ISSUES CLOSED -->
2072[gic]: https://badgen.net/github/closed-issues/sindresorhus/got?label
2073[kic]: https://badgen.net/github/closed-issues/sindresorhus/ky?label
2074[ric]: https://badgen.net/github/closed-issues/request/request?label
2075[nic]: https://badgen.net/github/closed-issues/bitinn/node-fetch?label
2076[aic]: https://badgen.net/github/closed-issues/axios/axios?label
2077[sic]: https://badgen.net/github/closed-issues/visionmedia/superagent?label
2078
2079[g2]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2080[k2]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2081[r2]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2082[n2]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2083[a2]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2084[s2]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2085
2086<!-- DOWNLOADS -->
2087[gd]: https://badgen.net/npm/dm/got?label
2088[kd]: https://badgen.net/npm/dm/ky?label
2089[rd]: https://badgen.net/npm/dm/request?label
2090[nd]: https://badgen.net/npm/dm/node-fetch?label
2091[ad]: https://badgen.net/npm/dm/axios?label
2092[sd]: https://badgen.net/npm/dm/superagent?label
2093
2094[g3]: https://www.npmjs.com/package/got
2095[k3]: https://www.npmjs.com/package/ky
2096[r3]: https://www.npmjs.com/package/request
2097[n3]: https://www.npmjs.com/package/node-fetch
2098[a3]: https://www.npmjs.com/package/axios
2099[s3]: https://www.npmjs.com/package/superagent
2100
2101<!-- COVERAGE -->
2102[gc]: https://badgen.net/coveralls/c/github/sindresorhus/got?label
2103[kc]: https://badgen.net/codecov/c/github/sindresorhus/ky?label
2104[rc]: https://badgen.net/coveralls/c/github/request/request?label
2105[nc]: https://badgen.net/coveralls/c/github/bitinn/node-fetch?label
2106[ac]: https://badgen.net/coveralls/c/github/mzabriskie/axios?label
2107[sc]: https://badgen.net/codecov/c/github/visionmedia/superagent?label
2108
2109[g4]: https://coveralls.io/github/sindresorhus/got
2110[k4]: https://codecov.io/gh/sindresorhus/ky
2111[r4]: https://coveralls.io/github/request/request
2112[n4]: https://coveralls.io/github/bitinn/node-fetch
2113[a4]: https://coveralls.io/github/mzabriskie/axios
2114[s4]: https://codecov.io/gh/visionmedia/superagent
2115
2116<!-- BUILD -->
2117[gb]: https://badgen.net/travis/sindresorhus/got?label
2118[kb]: https://badgen.net/travis/sindresorhus/ky?label
2119[rb]: https://badgen.net/travis/request/request?label
2120[nb]: https://badgen.net/travis/bitinn/node-fetch?label
2121[ab]: https://badgen.net/travis/axios/axios?label
2122[sb]: https://badgen.net/travis/visionmedia/superagent?label
2123
2124[g5]: https://travis-ci.org/sindresorhus/got
2125[k5]: https://travis-ci.org/sindresorhus/ky
2126[r5]: https://travis-ci.org/request/request
2127[n5]: https://travis-ci.org/bitinn/node-fetch
2128[a5]: https://travis-ci.org/axios/axios
2129[s5]: https://travis-ci.org/visionmedia/superagent
2130
2131<!-- BUGS -->
2132[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
2133[kbg]: https://badgen.net/github/label-issues/sindresorhus/ky/bug/open?label
2134[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open?label
2135[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open?label
2136[abg]: https://badgen.net/github/label-issues/axios/axios/type:confirmed%20bug/open?label
2137[sbg]: https://badgen.net/github/label-issues/visionmedia/superagent/Bug/open?label
2138
2139[g6]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2140[k6]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2141[r6]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A"Needs+investigation"
2142[n6]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2143[a6]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22type%3Aconfirmed+bug%22
2144[s6]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3ABug
2145
2146<!-- DEPENDENTS -->
2147[gdp]: https://badgen.net/npm/dependents/got?label
2148[kdp]: https://badgen.net/npm/dependents/ky?label
2149[rdp]: https://badgen.net/npm/dependents/request?label
2150[ndp]: https://badgen.net/npm/dependents/node-fetch?label
2151[adp]: https://badgen.net/npm/dependents/axios?label
2152[sdp]: https://badgen.net/npm/dependents/superagent?label
2153
2154[g7]: https://www.npmjs.com/package/got?activeTab=dependents
2155[k7]: https://www.npmjs.com/package/ky?activeTab=dependents
2156[r7]: https://www.npmjs.com/package/request?activeTab=dependents
2157[n7]: https://www.npmjs.com/package/node-fetch?activeTab=dependents
2158[a7]: https://www.npmjs.com/package/axios?activeTab=dependents
2159[s7]: https://www.npmjs.com/package/visionmedia?activeTab=dependents
2160
2161<!-- INSTALL SIZE -->
2162[gis]: https://badgen.net/packagephobia/install/got?label
2163[kis]: https://badgen.net/packagephobia/install/ky?label
2164[ris]: https://badgen.net/packagephobia/install/request?label
2165[nis]: https://badgen.net/packagephobia/install/node-fetch?label
2166[ais]: https://badgen.net/packagephobia/install/axios?label
2167[sis]: https://badgen.net/packagephobia/install/superagent?label
2168
2169[g8]: https://packagephobia.now.sh/result?p=got
2170[k8]: https://packagephobia.now.sh/result?p=ky
2171[r8]: https://packagephobia.now.sh/result?p=request
2172[n8]: https://packagephobia.now.sh/result?p=node-fetch
2173[a8]: https://packagephobia.now.sh/result?p=axios
2174[s8]: https://packagephobia.now.sh/result?p=superagent
2175
2176<!-- GITHUB STARS -->
2177[gs]: https://badgen.net/github/stars/sindresorhus/got?label
2178[ks]: https://badgen.net/github/stars/sindresorhus/ky?label
2179[rs]: https://badgen.net/github/stars/request/request?label
2180[ns]: https://badgen.net/github/stars/bitinn/node-fetch?label
2181[as]: https://badgen.net/github/stars/axios/axios?label
2182[ss]: https://badgen.net/github/stars/visionmedia/superagent?label
2183
2184[g9]: https://github.com/sindresorhus/got
2185[k9]: https://github.com/sindresorhus/ky
2186[r9]: https://github.com/request/request
2187[n9]: https://github.com/node-fetch/node-fetch
2188[a9]: https://github.com/axios/axios
2189[s9]: https://github.com/visionmedia/superagent
2190
2191<!-- TYPESCRIPT SUPPORT -->
2192[gts]: https://badgen.net/npm/types/got?label
2193[kts]: https://badgen.net/npm/types/ky?label
2194[rts]: https://badgen.net/npm/types/request?label
2195[nts]: https://badgen.net/npm/types/node-fetch?label
2196[ats]: https://badgen.net/npm/types/axios?label
2197[sts]: https://badgen.net/npm/types/superagent?label
2198
2199[g10]: https://github.com/sindresorhus/got
2200[k10]: https://github.com/sindresorhus/ky
2201[r10]: https://github.com/request/request
2202[n10]: https://github.com/node-fetch/node-fetch
2203[a10]: https://github.com/axios/axios
2204[s10]: https://github.com/visionmedia/superagent
2205
2206<!-- LAST COMMIT -->
2207[glc]: https://badgen.net/github/last-commit/sindresorhus/got?label
2208[klc]: https://badgen.net/github/last-commit/sindresorhus/ky?label
2209[rlc]: https://badgen.net/github/last-commit/request/request?label
2210[nlc]: https://badgen.net/github/last-commit/bitinn/node-fetch?label
2211[alc]: https://badgen.net/github/last-commit/axios/axios?label
2212[slc]: https://badgen.net/github/last-commit/visionmedia/superagent?label
2213
2214[g11]: https://github.com/sindresorhus/got/commits
2215[k11]: https://github.com/sindresorhus/ky/commits
2216[r11]: https://github.com/request/request/commits
2217[n11]: https://github.com/node-fetch/node-fetch/commits
2218[a11]: https://github.com/axios/axios/commits
2219[s11]: https://github.com/visionmedia/superagent/commits
2220
2221[Click here][InstallSizeOfTheDependencies] to see the install size of the Got dependencies.
2222
2223[InstallSizeOfTheDependencies]: https://packagephobia.com/result?p=@sindresorhus/is@3.0.0,@szmarczak/http-timer@4.0.5,@types/cacheable-request@6.0.1,@types/responselike@1.0.0,cacheable-lookup@5.0.3,cacheable-request@7.0.1,decompress-response@6.0.0,http2-wrapper@1.0.0,lowercase-keys@2.0.0,p-cancelable@2.0.0,responselike@2.0.0
2224
2225## Related
2226
2227- [gh-got](https://github.com/sindresorhus/gh-got) - Got convenience wrapper to interact with the GitHub API
2228- [gl-got](https://github.com/singapore/gl-got) - Got convenience wrapper to interact with the GitLab API
2229- [travis-got](https://github.com/samverschueren/travis-got) - Got convenience wrapper to interact with the Travis API
2230- [graphql-got](https://github.com/kevva/graphql-got) - Got convenience wrapper to interact with GraphQL
2231- [GotQL](https://github.com/khaosdoctor/gotql) - Got convenience wrapper to interact with GraphQL using JSON-parsed queries instead of strings
2232- [got-fetch](https://github.com/alexghr/got-fetch) - Got with a `fetch` interface
2233
2234## Maintainers
2235
2236[![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)
2237---|---
2238[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak)
2239
2240###### Former
2241
2242- [Vsevolod Strukchinsky](https://github.com/floatdrop)
2243- [Alexander Tesfamichael](https://github.com/alextes)
2244- [Brandon Smith](https://github.com/brandon93s)
2245- [Luke Childs](https://github.com/lukechilds)
2246
2247## For enterprise
2248
2249Available as part of the Tidelift Subscription.
2250
2251The 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)