UNPKG

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