UNPKG

85.6 kBMarkdownView Raw
1<div align="center">
2 <br>
3 <br>
4 <img width="360" src="media/logo.svg" alt="Got">
5 <br>
6 <br>
7 <br>
8 <p align="center">Huge thanks to <a href="https://moxy.studio"><img src="https://sindresorhus.com/assets/thanks/moxy-logo.svg" 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`. 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.
1713
1714#### got.ReadError
1715
1716When reading from response stream fails.
1717
1718#### got.ParseError
1719
1720When server response code is 2xx, and parsing body fails. Includes a `response` property.
1721
1722#### got.UploadError
1723
1724When the request body is a stream and an error occurs while reading from that stream.
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.
1729
1730#### got.MaxRedirectsError
1731
1732When the server redirects you more than ten times. Includes a `response` property.
1733
1734#### got.UnsupportedProtocolError
1735
1736When given an unsupported protocol.
1737
1738#### got.TimeoutError
1739
1740When the request is aborted due to a [timeout](#timeout). Includes an `event` and `timings` property.
1741
1742#### got.CancelError
1743
1744When the request is aborted with `.cancel()`.
1745
1746## Aborting the request
1747
1748The promise returned by Got has a [`.cancel()`](https://github.com/sindresorhus/p-cancelable) method which when called, aborts the request.
1749
1750```js
1751(async () => {
1752 const request = got(url, options);
1753
1754 // …
1755
1756 // In another part of the code
1757 if (something) {
1758 request.cancel();
1759 }
1760
1761 // …
1762
1763 try {
1764 await request;
1765 } catch (error) {
1766 if (request.isCanceled) { // Or `error instanceof got.CancelError`
1767 // Handle cancelation
1768 }
1769
1770 // Handle other errors
1771 }
1772})();
1773```
1774
1775When using hooks, simply throw an error to abort the request.
1776
1777```js
1778const got = require('got');
1779
1780(async () => {
1781 const request = got(url, {
1782 hooks: {
1783 beforeRequest: [
1784 () => {
1785 throw new Error('Oops. Request canceled.');
1786 }
1787 ]
1788 }
1789 });
1790
1791 try {
1792 await request;
1793 } catch (error) {
1794 // …
1795 }
1796})();
1797```
1798
1799To abort the Got Stream request, just call `stream.destroy()`.
1800
1801```js
1802const got = require('got');
1803
1804const stream = got.stream(url);
1805stream.destroy();
1806```
1807
1808<a name="cache-adapters"></a>
1809## Cache
1810
1811Got 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).
1812
1813You can use the JavaScript `Map` type as an in-memory cache:
1814
1815```js
1816const got = require('got');
1817
1818const map = new Map();
1819
1820(async () => {
1821 let response = await got('https://sindresorhus.com', {cache: map});
1822 console.log(response.isFromCache);
1823 //=> false
1824
1825 response = await got('https://sindresorhus.com', {cache: map});
1826 console.log(response.isFromCache);
1827 //=> true
1828})();
1829```
1830
1831Got 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):
1832
1833```
1834$ npm install @keyv/redis
1835```
1836
1837```js
1838const got = require('got');
1839const KeyvRedis = require('@keyv/redis');
1840
1841const redis = new KeyvRedis('redis://user:pass@localhost:6379');
1842
1843got('https://sindresorhus.com', {cache: redis});
1844```
1845
1846Got supports anything that follows the Map API, so it's easy to write your own storage adapter or use a third-party solution.
1847
1848For example, the following are all valid storage adapters:
1849
1850```js
1851const storageAdapter = new Map();
1852// Or
1853const storageAdapter = require('./my-storage-adapter');
1854// Or
1855const QuickLRU = require('quick-lru');
1856const storageAdapter = new QuickLRU({maxSize: 1000});
1857
1858got('https://sindresorhus.com', {cache: storageAdapter});
1859```
1860
1861View the [Keyv docs](https://github.com/lukechilds/keyv) for more information on how to use storage adapters.
1862
1863## Proxies
1864
1865You can use the [`tunnel`](https://github.com/koichik/node-tunnel) package with the `agent` option to work with proxies:
1866
1867```js
1868const got = require('got');
1869const tunnel = require('tunnel');
1870
1871got('https://sindresorhus.com', {
1872 agent: {
1873 https: tunnel.httpsOverHttp({
1874 proxy: {
1875 host: 'localhost'
1876 }
1877 })
1878 }
1879});
1880```
1881
1882Otherwise, you can use the [`hpagent`](https://github.com/delvedor/hpagent) package, which keeps the internal sockets alive to be reused.
1883
1884```js
1885const got = require('got');
1886const {HttpsProxyAgent} = require('hpagent');
1887
1888got('https://sindresorhus.com', {
1889 agent: {
1890 https: new HttpsProxyAgent({
1891 keepAlive: true,
1892 keepAliveMsecs: 1000,
1893 maxSockets: 256,
1894 maxFreeSockets: 256,
1895 scheduling: 'lifo',
1896 proxy: 'https://localhost:8080'
1897 })
1898 }
1899});
1900```
1901
1902Alternatively, use [`global-agent`](https://github.com/gajus/global-agent) to configure a global proxy for all HTTP/HTTPS traffic in your program.
1903
1904Read the [`http2-wrapper`](https://github.com/szmarczak/http2-wrapper/#proxy-support) docs to learn about proxying for HTTP/2.
1905
1906## Cookies
1907
1908You can use the [`tough-cookie`](https://github.com/salesforce/tough-cookie) package:
1909
1910```js
1911const {promisify} = require('util');
1912const got = require('got');
1913const {CookieJar} = require('tough-cookie');
1914
1915(async () => {
1916 const cookieJar = new CookieJar();
1917 const setCookie = promisify(cookieJar.setCookie.bind(cookieJar));
1918
1919 await setCookie('foo=bar', 'https://example.com');
1920 await got('https://example.com', {cookieJar});
1921})();
1922```
1923
1924## Form data
1925
1926You can use the [`form-data`](https://github.com/form-data/form-data) package to create POST request with form data:
1927
1928```js
1929const fs = require('fs');
1930const got = require('got');
1931const FormData = require('form-data');
1932
1933const form = new FormData();
1934
1935form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
1936
1937got.post('https://example.com', {
1938 body: form
1939});
1940```
1941
1942## OAuth
1943
1944You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) package to create a signed OAuth request:
1945
1946```js
1947const got = require('got');
1948const crypto = require('crypto');
1949const OAuth = require('oauth-1.0a');
1950
1951const oauth = OAuth({
1952 consumer: {
1953 key: process.env.CONSUMER_KEY,
1954 secret: process.env.CONSUMER_SECRET
1955 },
1956 signature_method: 'HMAC-SHA1',
1957 hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
1958});
1959
1960const token = {
1961 key: process.env.ACCESS_TOKEN,
1962 secret: process.env.ACCESS_TOKEN_SECRET
1963};
1964
1965const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
1966
1967got(url, {
1968 headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
1969 responseType: 'json'
1970});
1971```
1972
1973## Unix Domain Sockets
1974
1975Requests 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`.
1976
1977- `PROTOCOL` - `http` or `https` *(optional)*
1978- `SOCKET` - Absolute path to a unix domain socket, for example: `/var/run/docker.sock`
1979- `PATH` - Request path, for example: `/v2/keys`
1980
1981```js
1982const got = require('got');
1983
1984got('http://unix:/var/run/docker.sock:/containers/json');
1985
1986// Or without protocol (HTTP by default)
1987got('unix:/var/run/docker.sock:/containers/json');
1988```
1989
1990## AWS
1991
1992Requests 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.
1993
1994```js
1995const got4aws = require('got4aws');;
1996
1997const awsClient = got4aws();
1998
1999const response = await awsClient('https://<api-id>.execute-api.<api-region>.amazonaws.com/<stage>/endpoint/path', {
2000 // Request-specific options
2001});
2002```
2003
2004## Testing
2005
2006You can test your requests by using the [`nock`](https://github.com/node-nock/nock) package to mock an endpoint:
2007
2008```js
2009const got = require('got');
2010const nock = require('nock');
2011
2012nock('https://sindresorhus.com')
2013 .get('/')
2014 .reply(200, 'Hello world!');
2015
2016(async () => {
2017 const response = await got('https://sindresorhus.com');
2018 console.log(response.body);
2019 //=> 'Hello world!'
2020})();
2021```
2022
2023Bear 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.
2024
2025```js
2026const got = require('got');
2027const nock = require('nock');
2028
2029const scope = nock('https://sindresorhus.com')
2030 .get('/')
2031 .reply(500, 'Internal server error')
2032 .persist();
2033
2034(async () => {
2035 try {
2036 await got('https://sindresorhus.com')
2037 } catch (error) {
2038 console.log(error.response.body);
2039 //=> 'Internal server error'
2040
2041 console.log(error.response.retryCount);
2042 //=> 2
2043 }
2044
2045 scope.persist(false);
2046})();
2047```
2048
2049For 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:
2050
2051```js
2052test('retry function gets iteration count', withServer, async (t, server, got) => {
2053 let knocks = 0;
2054 server.get('/', (request, response) => {
2055 if (knocks++ === 1) {
2056 response.end('who`s there?');
2057 }
2058 });
2059
2060 await got({
2061 retry: {
2062 calculateDelay: ({attemptCount}) => {
2063 t.true(is.number(attemptCount));
2064 return attemptCount < 2 ? 1 : 0;
2065 }
2066 }
2067 });
2068});
2069```
2070
2071## Tips
2072
2073### JSON mode
2074
2075To pass an object as the body, you need to use the `json` option. It will be stringified using `JSON.stringify`. Example:
2076
2077```js
2078const got = require('got');
2079
2080(async () => {
2081 const {body} = await got.post('https://httpbin.org/anything', {
2082 json: {
2083 hello: 'world'
2084 },
2085 responseType: 'json'
2086 });
2087
2088 console.log(body.data);
2089 //=> '{"hello":"world"}'
2090})();
2091```
2092
2093To receive a JSON body you can either set `responseType` option to `json` or use `promise.json()`. Example:
2094
2095```js
2096const got = require('got');
2097
2098(async () => {
2099 const body = await got.post('https://httpbin.org/anything', {
2100 json: {
2101 hello: 'world'
2102 }
2103 }).json();
2104
2105 console.log(body);
2106 //=> {…}
2107})();
2108```
2109
2110### User Agent
2111
2112It'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`.
2113
2114```js
2115const got = require('got');
2116const pkg = require('./package.json');
2117
2118got('https://sindresorhus.com', {
2119 headers: {
2120 'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
2121 }
2122});
2123
2124got('https://sindresorhus.com', {
2125 headers: {
2126 'user-agent': undefined
2127 }
2128});
2129```
2130
2131### 304 Responses
2132
2133Bear 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.
2134
2135### Custom endpoints
2136
2137Use `got.extend()` to make it nicer to work with REST APIs. Especially if you use the `prefixUrl` option.
2138
2139```js
2140const got = require('got');
2141const pkg = require('./package.json');
2142
2143const custom = got.extend({
2144 prefixUrl: 'example.com',
2145 responseType: 'json',
2146 headers: {
2147 'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
2148 }
2149});
2150
2151// Use `custom` exactly how you use `got`
2152(async () => {
2153 const list = await custom('v1/users/list');
2154})();
2155```
2156
2157## FAQ
2158
2159### Why yet another HTTP client?
2160
2161Got 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)\
2162Furthermore, Got is fully written in TypeScript and actively maintained.
2163
2164### Electron support has been removed
2165
2166The Electron `net` module is not consistent with the Node.js `http` module. See [#899](https://github.com/sindresorhus/got/issues/899) for more info.
2167
2168## Comparison
2169
2170| | `got` | [`request`][r0] | [`node-fetch`][n0] | [`ky`][k0] | [`axios`][a0] | [`superagent`][s0] |
2171|-----------------------|:------------------:|:------------------:|:--------------------:|:------------------------:|:------------------:|:----------------------:|
2172| HTTP/2 support | :sparkle: | :x: | :x: | :x: | :x: | :heavy_check_mark:\*\* |
2173| Browser support | :x: | :x: | :heavy_check_mark:\* | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2174| Promise API | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2175| Stream API | :heavy_check_mark: | :heavy_check_mark: | Node.js only | :x: | :x: | :heavy_check_mark: |
2176| Pagination API | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2177| Request cancelation | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2178| RFC compliant caching | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2179| Cookies (out-of-box) | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
2180| Follows redirects | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2181| Retries on failure | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :x: | :heavy_check_mark: |
2182| Progress events | :heavy_check_mark: | :x: | :x: | :heavy_check_mark:\*\*\* | Browser only | :heavy_check_mark: |
2183| Handles gzip/deflate | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2184| Advanced timeouts | :heavy_check_mark: | :x: | :x: | :x: | :x: | :x: |
2185| Timings | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :x: | :x: |
2186| Errors with metadata | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2187| JSON mode | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
2188| Custom defaults | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2189| Composable | :heavy_check_mark: | :x: | :x: | :x: | :x: | :heavy_check_mark: |
2190| Hooks | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: |
2191| Issues open | [![][gio]][g1] | [![][rio]][r1] | [![][nio]][n1] | [![][kio]][k1] | [![][aio]][a1] | [![][sio]][s1] |
2192| Issues closed | [![][gic]][g2] | [![][ric]][r2] | [![][nic]][n2] | [![][kic]][k2] | [![][aic]][a2] | [![][sic]][s2] |
2193| Downloads | [![][gd]][g3] | [![][rd]][r3] | [![][nd]][n3] | [![][kd]][k3] | [![][ad]][a3] | [![][sd]][s3] |
2194| Coverage | [![][gc]][g4] | [![][rc]][r4] | [![][nc]][n4] | [![][kc]][k4] | [![][ac]][a4] | [![][sc]][s4] |
2195| Build | [![][gb]][g5] | [![][rb]][r5] | [![][nb]][n5] | [![][kb]][k5] | [![][ab]][a5] | [![][sb]][s5] |
2196| Bugs | [![][gbg]][g6] | [![][rbg]][r6] | [![][nbg]][n6] | [![][kbg]][k6] | [![][abg]][a6] | [![][sbg]][s6] |
2197| Dependents | [![][gdp]][g7] | [![][rdp]][r7] | [![][ndp]][n7] | [![][kdp]][k7] | [![][adp]][a7] | [![][sdp]][s7] |
2198| Install size | [![][gis]][g8] | [![][ris]][r8] | [![][nis]][n8] | [![][kis]][k8] | [![][ais]][a8] | [![][sis]][s8] |
2199| GitHub stars | [![][gs]][g9] | [![][rs]][r9] | [![][ns]][n9] | [![][ks]][k9] | [![][as]][a9] | [![][ss]][s9] |
2200| TypeScript support | [![][gts]][g10] | [![][rts]][r10] | [![][nts]][n10] | [![][kts]][k10] | [![][ats]][a10] | [![][sts]][s11] |
2201| Last commit | [![][glc]][g11] | [![][rlc]][r11] | [![][nlc]][n11] | [![][klc]][k11] | [![][alc]][a11] | [![][slc]][s11] |
2202
2203\* It's almost API compatible with the browser `fetch` API.\
2204\*\* Need to switch the protocol manually. Doesn't accept PUSH streams and doesn't reuse HTTP/2 sessions.\
2205\*\*\* Currently, only `DownloadProgress` event is supported, `UploadProgress` event is not supported.\
2206:sparkle: Almost-stable feature, but the API may change. Don't hesitate to try it out!\
2207:grey_question: Feature in early stage of development. Very experimental.
2208
2209<!-- GITHUB -->
2210[k0]: https://github.com/sindresorhus/ky
2211[r0]: https://github.com/request/request
2212[n0]: https://github.com/node-fetch/node-fetch
2213[a0]: https://github.com/axios/axios
2214[s0]: https://github.com/visionmedia/superagent
2215
2216<!-- ISSUES OPEN -->
2217[gio]: https://badgen.net/github/open-issues/sindresorhus/got?label
2218[kio]: https://badgen.net/github/open-issues/sindresorhus/ky?label
2219[rio]: https://badgen.net/github/open-issues/request/request?label
2220[nio]: https://badgen.net/github/open-issues/bitinn/node-fetch?label
2221[aio]: https://badgen.net/github/open-issues/axios/axios?label
2222[sio]: https://badgen.net/github/open-issues/visionmedia/superagent?label
2223
2224[g1]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2225[k1]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2226[r1]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2227[n1]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2228[a1]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2229[s1]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
2230
2231<!-- ISSUES CLOSED -->
2232[gic]: https://badgen.net/github/closed-issues/sindresorhus/got?label
2233[kic]: https://badgen.net/github/closed-issues/sindresorhus/ky?label
2234[ric]: https://badgen.net/github/closed-issues/request/request?label
2235[nic]: https://badgen.net/github/closed-issues/bitinn/node-fetch?label
2236[aic]: https://badgen.net/github/closed-issues/axios/axios?label
2237[sic]: https://badgen.net/github/closed-issues/visionmedia/superagent?label
2238
2239[g2]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2240[k2]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2241[r2]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2242[n2]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2243[a2]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2244[s2]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
2245
2246<!-- DOWNLOADS -->
2247[gd]: https://badgen.net/npm/dm/got?label
2248[kd]: https://badgen.net/npm/dm/ky?label
2249[rd]: https://badgen.net/npm/dm/request?label
2250[nd]: https://badgen.net/npm/dm/node-fetch?label
2251[ad]: https://badgen.net/npm/dm/axios?label
2252[sd]: https://badgen.net/npm/dm/superagent?label
2253
2254[g3]: https://www.npmjs.com/package/got
2255[k3]: https://www.npmjs.com/package/ky
2256[r3]: https://www.npmjs.com/package/request
2257[n3]: https://www.npmjs.com/package/node-fetch
2258[a3]: https://www.npmjs.com/package/axios
2259[s3]: https://www.npmjs.com/package/superagent
2260
2261<!-- COVERAGE -->
2262[gc]: https://badgen.net/coveralls/c/github/sindresorhus/got?label
2263[kc]: https://badgen.net/codecov/c/github/sindresorhus/ky?label
2264[rc]: https://badgen.net/coveralls/c/github/request/request?label
2265[nc]: https://badgen.net/coveralls/c/github/bitinn/node-fetch?label
2266[ac]: https://badgen.net/coveralls/c/github/mzabriskie/axios?label
2267[sc]: https://badgen.net/codecov/c/github/visionmedia/superagent?label
2268
2269[g4]: https://coveralls.io/github/sindresorhus/got
2270[k4]: https://codecov.io/gh/sindresorhus/ky
2271[r4]: https://coveralls.io/github/request/request
2272[n4]: https://coveralls.io/github/bitinn/node-fetch
2273[a4]: https://coveralls.io/github/mzabriskie/axios
2274[s4]: https://codecov.io/gh/visionmedia/superagent
2275
2276<!-- BUILD -->
2277[gb]: https://badgen.net/travis/sindresorhus/got?label
2278[kb]: https://badgen.net/travis/sindresorhus/ky?label
2279[rb]: https://badgen.net/travis/request/request?label
2280[nb]: https://badgen.net/travis/bitinn/node-fetch?label
2281[ab]: https://badgen.net/travis/axios/axios?label
2282[sb]: https://badgen.net/travis/visionmedia/superagent?label
2283
2284[g5]: https://travis-ci.com/github/sindresorhus/got
2285[k5]: https://travis-ci.com/github/sindresorhus/ky
2286[r5]: https://travis-ci.org/github/request/request
2287[n5]: https://travis-ci.org/github/bitinn/node-fetch
2288[a5]: https://travis-ci.org/github/axios/axios
2289[s5]: https://travis-ci.org/github/visionmedia/superagent
2290
2291<!-- BUGS -->
2292[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
2293[kbg]: https://badgen.net/github/label-issues/sindresorhus/ky/bug/open?label
2294[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open?label
2295[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open?label
2296[abg]: https://badgen.net/github/label-issues/axios/axios/type:confirmed%20bug/open?label
2297[sbg]: https://badgen.net/github/label-issues/visionmedia/superagent/Bug/open?label
2298
2299[g6]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2300[k6]: https://github.com/sindresorhus/ky/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2301[r6]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A"Needs+investigation"
2302[n6]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
2303[a6]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22type%3Aconfirmed+bug%22
2304[s6]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3ABug
2305
2306<!-- DEPENDENTS -->
2307[gdp]: https://badgen.net/npm/dependents/got?label
2308[kdp]: https://badgen.net/npm/dependents/ky?label
2309[rdp]: https://badgen.net/npm/dependents/request?label
2310[ndp]: https://badgen.net/npm/dependents/node-fetch?label
2311[adp]: https://badgen.net/npm/dependents/axios?label
2312[sdp]: https://badgen.net/npm/dependents/superagent?label
2313
2314[g7]: https://www.npmjs.com/package/got?activeTab=dependents
2315[k7]: https://www.npmjs.com/package/ky?activeTab=dependents
2316[r7]: https://www.npmjs.com/package/request?activeTab=dependents
2317[n7]: https://www.npmjs.com/package/node-fetch?activeTab=dependents
2318[a7]: https://www.npmjs.com/package/axios?activeTab=dependents
2319[s7]: https://www.npmjs.com/package/visionmedia?activeTab=dependents
2320
2321<!-- INSTALL SIZE -->
2322[gis]: https://badgen.net/packagephobia/install/got?label
2323[kis]: https://badgen.net/packagephobia/install/ky?label
2324[ris]: https://badgen.net/packagephobia/install/request?label
2325[nis]: https://badgen.net/packagephobia/install/node-fetch?label
2326[ais]: https://badgen.net/packagephobia/install/axios?label
2327[sis]: https://badgen.net/packagephobia/install/superagent?label
2328
2329[g8]: https://packagephobia.now.sh/result?p=got
2330[k8]: https://packagephobia.now.sh/result?p=ky
2331[r8]: https://packagephobia.now.sh/result?p=request
2332[n8]: https://packagephobia.now.sh/result?p=node-fetch
2333[a8]: https://packagephobia.now.sh/result?p=axios
2334[s8]: https://packagephobia.now.sh/result?p=superagent
2335
2336<!-- GITHUB STARS -->
2337[gs]: https://badgen.net/github/stars/sindresorhus/got?label
2338[ks]: https://badgen.net/github/stars/sindresorhus/ky?label
2339[rs]: https://badgen.net/github/stars/request/request?label
2340[ns]: https://badgen.net/github/stars/bitinn/node-fetch?label
2341[as]: https://badgen.net/github/stars/axios/axios?label
2342[ss]: https://badgen.net/github/stars/visionmedia/superagent?label
2343
2344[g9]: https://github.com/sindresorhus/got
2345[k9]: https://github.com/sindresorhus/ky
2346[r9]: https://github.com/request/request
2347[n9]: https://github.com/node-fetch/node-fetch
2348[a9]: https://github.com/axios/axios
2349[s9]: https://github.com/visionmedia/superagent
2350
2351<!-- TYPESCRIPT SUPPORT -->
2352[gts]: https://badgen.net/npm/types/got?label
2353[kts]: https://badgen.net/npm/types/ky?label
2354[rts]: https://badgen.net/npm/types/request?label
2355[nts]: https://badgen.net/npm/types/node-fetch?label
2356[ats]: https://badgen.net/npm/types/axios?label
2357[sts]: https://badgen.net/npm/types/superagent?label
2358
2359[g10]: https://github.com/sindresorhus/got
2360[k10]: https://github.com/sindresorhus/ky
2361[r10]: https://github.com/request/request
2362[n10]: https://github.com/node-fetch/node-fetch
2363[a10]: https://github.com/axios/axios
2364[s10]: https://github.com/visionmedia/superagent
2365
2366<!-- LAST COMMIT -->
2367[glc]: https://badgen.net/github/last-commit/sindresorhus/got?label
2368[klc]: https://badgen.net/github/last-commit/sindresorhus/ky?label
2369[rlc]: https://badgen.net/github/last-commit/request/request?label
2370[nlc]: https://badgen.net/github/last-commit/bitinn/node-fetch?label
2371[alc]: https://badgen.net/github/last-commit/axios/axios?label
2372[slc]: https://badgen.net/github/last-commit/visionmedia/superagent?label
2373
2374[g11]: https://github.com/sindresorhus/got/commits
2375[k11]: https://github.com/sindresorhus/ky/commits
2376[r11]: https://github.com/request/request/commits
2377[n11]: https://github.com/node-fetch/node-fetch/commits
2378[a11]: https://github.com/axios/axios/commits
2379[s11]: https://github.com/visionmedia/superagent/commits
2380
2381[Click here][InstallSizeOfTheDependencies] to see the install size of the Got dependencies.
2382
2383[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
2384
2385## Related
2386
2387- [gh-got](https://github.com/sindresorhus/gh-got) - Got convenience wrapper to interact with the GitHub API
2388- [gl-got](https://github.com/singapore/gl-got) - Got convenience wrapper to interact with the GitLab API
2389- [travis-got](https://github.com/samverschueren/travis-got) - Got convenience wrapper to interact with the Travis API
2390- [graphql-got](https://github.com/kevva/graphql-got) - Got convenience wrapper to interact with GraphQL
2391- [GotQL](https://github.com/khaosdoctor/gotql) - Got convenience wrapper to interact with GraphQL using JSON-parsed queries instead of strings
2392- [got-fetch](https://github.com/alexghr/got-fetch) - Got with a `fetch` interface
2393
2394## Maintainers
2395
2396[![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)
2397---|---|---
2398[Sindre Sorhus](https://sindresorhus.com) | [Szymon Marczak](https://github.com/szmarczak) | [Giovanni Minotti](https://github.com/Giotino)
2399
2400###### Former
2401
2402- [Vsevolod Strukchinsky](https://github.com/floatdrop)
2403- [Alexander Tesfamichael](https://github.com/alextes)
2404- [Brandon Smith](https://github.com/brandon93s)
2405- [Luke Childs](https://github.com/lukechilds)
2406
2407<a name="widely-used"></a>
2408## These amazing companies are using Got
2409
2410<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>
2411&nbsp;&nbsp;&nbsp;&nbsp;
2412<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>
2413&nbsp;&nbsp;&nbsp;&nbsp;
2414<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>
2415&nbsp;&nbsp;&nbsp;&nbsp;
2416<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>
2417&nbsp;&nbsp;&nbsp;&nbsp;
2418<a href="http://karaokes.moe"><img width="140" valign="middle" src="https://camo.githubusercontent.com/6860e5fa4684c14d8e1aa65df0aba4e6808ea1a9/687474703a2f2f6b6172616f6b65732e6d6f652f6173736574732f696d616765732f696e6465782e706e67"></a>
2419&nbsp;&nbsp;&nbsp;&nbsp;
2420<a href="https://github.com/renovatebot/renovate"><img width="150" valign="middle" src="https://camo.githubusercontent.com/206d470ac709b9a702a97b0c08d6f389a086793d/68747470733a2f2f72656e6f76617465626f742e636f6d2f696d616765732f6c6f676f2e737667"></a>
2421&nbsp;&nbsp;&nbsp;&nbsp;
2422<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>
2423&nbsp;&nbsp;&nbsp;&nbsp;
2424<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>
2425&nbsp;&nbsp;&nbsp;&nbsp;
2426<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>
2427&nbsp;&nbsp;&nbsp;&nbsp;
2428<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>
2429
2430<br>
2431
2432> 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.
2433>
2434> — <a href="https://github.com/vadimdemedes">Vadim Demedes</a>
2435
2436> 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.
2437>
2438> — <a href="https://github.com/mojavelinux">Dan Allen</a>
2439
2440> 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.
2441>
2442> — <a href="https://github.com/danielkalen">Daniel Kalen</a>
2443
2444> 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.
2445>
2446> — <a href="https://github.com/yamalight">Tim Ermilov</a>
2447
2448> Karaoke Mugen uses Got to fetch content updates from its online server.
2449>
2450> — <a href="https://github.com/AxelTerizaki">Axel Terizaki</a>
2451
2452> 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.
2453>
2454> — <a href="https://github.com/rarkins">Rhys Arkins</a>
2455
2456> Resistbot uses Got to communicate from the API frontend where all correspondence ingresses to the officials lookup database in back.
2457>
2458> — <a href="https://github.com/chris-erickson">Chris Erickson</a>
2459
2460> Natural Cycles is using Got to communicate with all kinds of 3rd-party REST APIs (over 9000!).
2461>
2462> — <a href="https://github.com/kirillgroshkov">Kirill Groshkov</a>
2463
2464> 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.
2465>
2466> — <a href="https://github.com/Kikobeats">Kiko Beats</a>
2467
2468> We’re using Got at Radity. Thanks for such an amazing work!
2469>
2470> — <a href="https://github.com/MirzayevFarid">Mirzayev Farid</a>
2471
2472## For enterprise
2473
2474Available as part of the Tidelift Subscription.
2475
2476The 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)