2020-04-28 16:46:47 +02:00
# request.js
> Send parameterized requests to GitHub’ s APIs with sensible defaults in browsers and Node
[](https://www.npmjs.com/package/@octokit/request )
2025-03-14 13:13:56 -07:00
[](https://github.com/octokit/request.js/actions?query=workflow%3ATest+branch%3Amain)
2020-04-28 16:46:47 +02:00
`@octokit/request` is a request library for browsers & node that makes it easier
to interact with [GitHub’ s REST API ](https://developer.github.com/v3/ ) and
[GitHub’ s GraphQL API ](https://developer.github.com/v4/guides/forming-calls/#the-graphql-endpoint ).
It uses [`@octokit/endpoint` ](https://github.com/octokit/endpoint.js ) to parse
2025-03-14 13:13:56 -07:00
the passed options and sends the request using [fetch ](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ). You can pass a custom `fetch` function using the `options.request.fetch` option, see below.
2020-04-28 16:46:47 +02:00
<!-- update table of contents by running `npx markdown-toc README.md -i` -->
<!-- toc -->
2025-03-14 13:13:56 -07:00
- [request.js ](#requestjs )
- [Features ](#features )
- [Usage ](#usage )
- [REST API example ](#rest-api-example )
- [GraphQL example ](#graphql-example )
- [Alternative: pass `method` \& `url` as part of options ](#alternative-pass-method--url-as-part-of-options )
- [Authentication ](#authentication )
- [request() ](#request )
- [`request.defaults()` ](#requestdefaults )
- [`request.endpoint` ](#requestendpoint )
- [Special cases ](#special-cases )
- [The `data` parameter – set request body directly ](#the-data-parameter--set-request-body-directly )
- [Set parameters for both the URL/query and the request body ](#set-parameters-for-both-the-urlquery-and-the-request-body )
- [Set a custom Agent to your requests ](#set-a-custom-agent-to-your-requests )
- [LICENSE ](#license )
2020-04-28 16:46:47 +02:00
<!-- tocstop -->
## Features
🤩 1:1 mapping of REST API endpoint documentation, e.g. [Add labels to an issue ](https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue ) becomes
``` js
2023-07-13 09:09:17 +00:00
request ( "POST /repos/{owner}/{repo}/issues/{number}/labels" , {
2020-04-28 16:46:47 +02:00
mediaType : {
2020-09-18 15:40:23 +01:00
previews : [ "symmetra" ] ,
2020-04-28 16:46:47 +02:00
} ,
owner : "octokit" ,
repo : "request.js" ,
number : 1 ,
2020-09-18 15:40:23 +01:00
labels : [ "🐛 bug" ] ,
2020-04-28 16:46:47 +02:00
} ) ;
```
👶 [Small bundle size ](https://bundlephobia.com/result?p=@octokit/request@5.0.3 ) (\<4kb minified + gzipped)
😎 [Authenticate ](#authentication ) with any of [GitHubs Authentication Strategies ](https://github.com/octokit/auth.js ).
👍 Sensible defaults
- `baseUrl` : `https://api.github.com`
- `headers.accept` : `application/vnd.github.v3+json`
2025-03-14 13:13:56 -07:00
- `headers['user-agent']` : `octokit-request.js/<current version> <OS information>` , e.g. `octokit-request.js/1.2.3 Node.js/10.15.0 (macOS Mojave; x64)`
2020-04-28 16:46:47 +02:00
👌 Simple to test: mock requests by passing a custom fetch method.
🧐 Simple to debug: Sets `error.request` to request options causing the error (with redacted credentials).
## Usage
<table>
<tbody valign=top align=left>
<tr><th>
Browsers
</th><td width=100%>
2025-03-14 13:13:56 -07:00
Load <code>@octokit/request </code> directly from <a href="https://esm.sh">esm.sh</a>
2020-04-28 16:46:47 +02:00
``` html
< script type = "module" >
2025-03-14 13:13:56 -07:00
import { request } from "https://esm.sh/@octokit/request" ;
2020-04-28 16:46:47 +02:00
< / script >
```
</td></tr>
<tr><th>
Node
</th><td>
Install with <code>npm install @octokit/request </code>
``` js
2025-03-14 13:13:56 -07:00
import { request } from "@octokit/request" ;
2020-04-28 16:46:47 +02:00
```
</td></tr>
</tbody>
</table>
### REST API example
``` js
// Following GitHub docs formatting:
// https://developer.github.com/v3/repos/#list-organization-repositories
2023-07-13 09:09:17 +00:00
const result = await request ( "GET /orgs/{org}/repos" , {
2020-04-28 16:46:47 +02:00
headers : {
2020-09-18 15:40:23 +01:00
authorization : "token 0000000000000000000000000000000000000001" ,
2020-04-28 16:46:47 +02:00
} ,
org : "octokit" ,
2020-09-18 15:40:23 +01:00
type : "private" ,
2020-04-28 16:46:47 +02:00
} ) ;
console . log ( ` ${ result . data . length } repos found. ` ) ;
```
### GraphQL example
For GraphQL request we recommend using [`@octokit/graphql` ](https://github.com/octokit/graphql.js#readme )
``` js
const result = await request ( "POST /graphql" , {
headers : {
2020-09-18 15:40:23 +01:00
authorization : "token 0000000000000000000000000000000000000001" ,
2020-04-28 16:46:47 +02:00
} ,
query : ` query ( $ login: String!) {
organization(login: $ login) {
repositories(privacy: PRIVATE) {
totalCount
}
}
} ` ,
variables : {
2020-09-18 15:40:23 +01:00
login : "octokit" ,
} ,
2020-04-28 16:46:47 +02:00
} ) ;
```
### Alternative: pass `method` & `url` as part of options
Alternatively, pass in a method and a url
``` js
const result = await request ( {
method : "GET" ,
2023-07-13 09:09:17 +00:00
url : "/orgs/{org}/repos" ,
2020-04-28 16:46:47 +02:00
headers : {
2020-09-18 15:40:23 +01:00
authorization : "token 0000000000000000000000000000000000000001" ,
2020-04-28 16:46:47 +02:00
} ,
org : "octokit" ,
2020-09-18 15:40:23 +01:00
type : "private" ,
2020-04-28 16:46:47 +02:00
} ) ;
```
## Authentication
The simplest way to authenticate a request is to set the `Authorization` header directly, e.g. to a [personal access token ](https://github.com/settings/tokens/ ).
``` js
const requestWithAuth = request . defaults ( {
headers : {
2020-09-18 15:40:23 +01:00
authorization : "token 0000000000000000000000000000000000000001" ,
} ,
2020-04-28 16:46:47 +02:00
} ) ;
2020-09-18 15:40:23 +01:00
const result = await requestWithAuth ( "GET /user" ) ;
2020-04-28 16:46:47 +02:00
```
For more complex authentication strategies such as GitHub Apps or Basic, we recommend the according authentication library exported by [`@octokit/auth` ](https://github.com/octokit/auth.js ).
``` js
2025-03-14 13:13:56 -07:00
import { createAppAuth } from "@octokit/auth-app" ;
2020-04-28 16:46:47 +02:00
const auth = createAppAuth ( {
2023-07-13 09:09:17 +00:00
appId : process . env . APP _ID ,
2020-04-28 16:46:47 +02:00
privateKey : process . env . PRIVATE _KEY ,
2020-09-18 15:40:23 +01:00
installationId : 123 ,
2020-04-28 16:46:47 +02:00
} ) ;
const requestWithAuth = request . defaults ( {
request : {
2020-09-18 15:40:23 +01:00
hook : auth . hook ,
2020-04-28 16:46:47 +02:00
} ,
mediaType : {
2020-09-18 15:40:23 +01:00
previews : [ "machine-man" ] ,
} ,
2020-04-28 16:46:47 +02:00
} ) ;
const { data : app } = await requestWithAuth ( "GET /app" ) ;
2023-07-13 09:09:17 +00:00
const { data : app } = await requestWithAuth (
"POST /repos/{owner}/{repo}/issues" ,
{
owner : "octocat" ,
repo : "hello-world" ,
title : "Hello from the engine room" ,
2025-03-14 13:13:56 -07:00
} ,
2023-07-13 09:09:17 +00:00
) ;
2020-04-28 16:46:47 +02:00
```
## request()
`request(route, options)` or `request(options)` .
**Options **
<table>
<thead>
<tr>
<th align=left>
name
</th>
<th align=left>
type
</th>
<th align=left>
description
</th>
</tr>
</thead>
<tr>
<th align=left>
<code>route</code>
</th>
<td>
String
</td>
<td>
2023-07-13 09:09:17 +00:00
**Required ** . If <code>route</code> is set it has to be a string consisting of the request method and URL, e.g. <code>GET /orgs/{org}</code>
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
<code>options.baseUrl</code>
</th>
<td>
String
</td>
<td>
2023-07-13 09:09:17 +00:00
The base URL that <code>route</code> or <code>url</code> will be prefixed with, if they use relative paths. <em>Defaults to <code>https://api.github.com</code></em>.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<th align=left>
<code>options.headers</code>
</th>
<td>
Object
</td>
<td>
Custom headers. Passed headers are merged with defaults:<br>
<em><code>headers['user-agent']</code> defaults to <code>octokit-rest.js/1.2.3</code> (where <code>1.2.3</code> is the released version)</em>.<br>
<em><code>headers['accept']</code> defaults to <code>application/vnd.github.v3+json</code>.<br> Use <code>options.mediaType.{format,previews}</code> to request API previews and custom media types.
</td>
</tr>
<tr>
<th align=left>
2025-03-14 13:13:56 -07:00
<code>options.method</code>
2020-04-28 16:46:47 +02:00
</th>
<td>
String
</td>
<td>
2025-03-14 13:13:56 -07:00
Any supported <a href="https://developer.github.com/v3/#http -verbs">http verb</a>, case-insensitive. <em>Defaults to <code>Get</code></em>.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
2025-03-14 13:13:56 -07:00
<code>options.mediaType.format</code>
2020-04-28 16:46:47 +02:00
</th>
<td>
2025-03-14 13:13:56 -07:00
String
2020-04-28 16:46:47 +02:00
</td>
<td>
2025-03-14 13:13:56 -07:00
Media type param, such as `raw` , `html` , or `full` . See <a href="https://developer.github.com/v3/media/">Media Types</a>.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
2025-03-14 13:13:56 -07:00
<code>options.mediaType.previews</code>
2020-04-28 16:46:47 +02:00
</th>
<td>
2025-03-14 13:13:56 -07:00
Array of strings
2020-04-28 16:46:47 +02:00
</td>
<td>
2025-03-14 13:13:56 -07:00
Name of previews, such as `mercy` , `symmetra` , or `scarlet-witch` . See <a href="https://docs.github.com/graphql/overview/schema-previews">GraphQL Schema Previews</a>.
Note that these only apply to GraphQL requests and have no effect on REST routes.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
<code>options.url</code>
</th>
<td>
String
</td>
<td>
2023-07-13 09:09:17 +00:00
**Required ** . A path or full URL which may contain <code>:variable</code> or <code>{variable}</code> placeholders,
e.g. <code>/orgs/{org}/repos</code>. The <code>url</code> is parsed using <a href="https://github.com/bramstein/url-template">url-template</a>.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
<code>options.data</code>
</th>
<td>
Any
</td>
<td>
Set request body directly instead of setting it to JSON based on additional parameters. See <a href="#data -parameter">"The `data` parameter"</a> below.
</td>
</tr>
2025-03-14 13:13:56 -07:00
2020-04-28 16:46:47 +02:00
<tr>
<th align=left>
<code>options.request.fetch</code>
</th>
<td>
Function
</td>
<td>
2025-03-14 13:13:56 -07:00
Custom replacement for <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch</a>. Useful for testing or request hooks.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
<code>options.request.hook</code>
</th>
<td>
Function
</td>
<td>
2025-03-14 13:13:56 -07:00
Function with the signature <code>hook(request, endpointOptions)</code>, where <code>endpointOptions</code> are the parsed options as returned by <a href="https://github.com/octokit/endpoint.js#endpointmergeroute -options-or-endpointmergeoptions"><code>endpoint.merge()</code></a>, and <code>request</code> is <a href="https://github.com/octokit/request.js#request "><code>request()</code></a>. This option works great in conjunction with <a href="https://github.com/gr2m/before-after-hook">before-after-hook</a>.
2020-04-28 16:46:47 +02:00
</td>
</tr>
<tr>
<th align=left>
<a name="options-request-signal"></a><code>options.request.signal</code>
</th>
<td>
<a href="https://github.com/bitinn/node-fetch/tree/e996bdab73baf996cf2dbf25643c8fe2698c3249#request -cancellation-with-abortsignal">new AbortController().signal</a>
</td>
<td>
Use an <code>AbortController</code> instance to cancel a request. In node you can only cancel streamed requests.
</td>
</tr>
<th align=left>
2023-07-13 09:09:17 +00:00
<code>options.request.log</code>
</th>
<td>
<code>object</code>
</td>
<td>
Used for internal logging. Defaults to <a href="https://developer.mozilla.org/en-US/docs/Web/API/console"><code>console</code></a>.
</td>
</tr>
2025-03-14 13:13:56 -07:00
</tr>
2023-07-13 09:09:17 +00:00
<th align=left>
2025-03-14 13:13:56 -07:00
<code>options.request.parseSuccessResponseBody</code>
2020-04-28 16:46:47 +02:00
</th>
<td>
2025-03-14 13:13:56 -07:00
<code>boolean</code>
2020-04-28 16:46:47 +02:00
</td>
<td>
2025-03-14 13:13:56 -07:00
If set to <code>false</code> the returned `response` will be passed through from `fetch` . This is useful to stream response.body when downloading files from the GitHub API.
2020-04-28 16:46:47 +02:00
</td>
</tr>
</table>
All other options except `options.request.*` will be passed depending on the `method` and `url` options.
2023-07-13 09:09:17 +00:00
1. If the option key is a placeholder in the `url` , it will be used as replacement. For example, if the passed options are `{url: '/orgs/{org}/repos', org: 'foo'}` the returned `options.url` is `https://api.github.com/orgs/foo/repos`
2020-04-28 16:46:47 +02:00
2. If the `method` is `GET` or `HEAD` , the option is passed as query parameter
3. Otherwise the parameter is passed in the request body as JSON key.
**Result **
2025-03-14 13:13:56 -07:00
`request` returns a promise. If the request was successful, the promise resolves with an object containing 4 keys:
2020-04-28 16:46:47 +02:00
<table>
<thead>
<tr>
<th align=left>
key
</th>
<th align=left>
type
</th>
<th align=left>
description
</th>
</tr>
</thead>
<tr>
<th align=left><code>status</code></th>
<td>Integer</td>
<td>Response status status</td>
</tr>
<tr>
<th align=left><code>url</code></th>
<td>String</td>
<td>URL of response. If a request results in redirects, this is the final URL. You can send a <code>HEAD</code> request to retrieve it without loading the full response body.</td>
</tr>
<tr>
<th align=left><code>headers</code></th>
<td>Object</td>
<td>All response headers</td>
</tr>
<tr>
<th align=left><code>data</code></th>
<td>Any</td>
<td>The response body as returned from server. If the response is JSON then it will be parsed into an object</td>
</tr>
</table>
2025-03-14 13:13:56 -07:00
If an error occurs, the promise is rejected with an `error` object containing 3 keys to help with debugging:
2020-04-28 16:46:47 +02:00
- `error.status` The http response status code
- `error.request` The request options such as `method` , `url` and `data`
2023-07-13 09:09:17 +00:00
- `error.response` The http response object with `url` , `headers` , and `data`
2025-03-14 13:13:56 -07:00
If the error is due to an `AbortSignal` being used, the resulting `AbortError` is bubbled up to the caller.
2020-04-28 16:46:47 +02:00
## `request.defaults()`
Override or set default options. Example:
``` js
2025-03-14 13:13:56 -07:00
import { request } from "@octokit/request" ;
const myrequest = request . defaults ( {
2020-04-28 16:46:47 +02:00
baseUrl : "https://github-enterprise.acme-inc.com/api/v3" ,
headers : {
"user-agent" : "myApp/1.2.3" ,
2020-09-18 15:40:23 +01:00
authorization : ` token 0000000000000000000000000000000000000001 ` ,
2020-04-28 16:46:47 +02:00
} ,
org : "my-project" ,
2020-09-18 15:40:23 +01:00
per _page : 100 ,
2020-04-28 16:46:47 +02:00
} ) ;
2023-07-13 09:09:17 +00:00
myrequest ( ` GET /orgs/{org}/repos ` ) ;
2020-04-28 16:46:47 +02:00
```
You can call `.defaults()` again on the returned method, the defaults will cascade.
``` js
const myProjectRequest = request . defaults ( {
baseUrl : "https://github-enterprise.acme-inc.com/api/v3" ,
headers : {
2020-09-18 15:40:23 +01:00
"user-agent" : "myApp/1.2.3" ,
2020-04-28 16:46:47 +02:00
} ,
2020-09-18 15:40:23 +01:00
org : "my-project" ,
2020-04-28 16:46:47 +02:00
} ) ;
const myProjectRequestWithAuth = myProjectRequest . defaults ( {
headers : {
2020-09-18 15:40:23 +01:00
authorization : ` token 0000000000000000000000000000000000000001 ` ,
} ,
2020-04-28 16:46:47 +02:00
} ) ;
```
`myProjectRequest` now defaults the `baseUrl` , `headers['user-agent']` ,
`org` and `headers['authorization']` on top of `headers['accept']` that is set
by the global default.
## `request.endpoint`
See https://github.com/octokit/endpoint.js. Example
``` js
2023-07-13 09:09:17 +00:00
const options = request . endpoint ( "GET /orgs/{org}/repos" , {
2020-04-28 16:46:47 +02:00
org : "my-project" ,
2020-09-18 15:40:23 +01:00
type : "private" ,
2020-04-28 16:46:47 +02:00
} ) ;
// {
// method: 'GET',
// url: 'https://api.github.com/orgs/my-project/repos?type=private',
// headers: {
// accept: 'application/vnd.github.v3+json',
// authorization: 'token 0000000000000000000000000000000000000001',
// 'user-agent': 'octokit/endpoint.js v1.2.3'
// }
// }
```
All of the [`@octokit/endpoint` ](https://github.com/octokit/endpoint.js ) API can be used:
- [`octokitRequest.endpoint()` ](#endpoint )
- [`octokitRequest.endpoint.defaults()` ](#endpointdefaults )
- [`octokitRequest.endpoint.merge()` ](#endpointdefaults )
- [`octokitRequest.endpoint.parse()` ](#endpointmerge )
## Special cases
<a name="data-parameter"></a>
### The `data` parameter – set request body directly
Some endpoints such as [Render a Markdown document in raw mode ](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode ) don’ t have parameters that are sent as request body keys, instead the request body needs to be set directly. In these cases, set the `data` parameter.
``` js
const response = await request ( "POST /markdown/raw" , {
data : "Hello world github/linguist#1 **cool**, and #1!" ,
headers : {
accept : "text/html;charset=utf-8" ,
2020-09-18 15:40:23 +01:00
"content-type" : "text/plain" ,
} ,
2020-04-28 16:46:47 +02:00
} ) ;
// Request is sent as
//
// {
// method: 'post',
// url: 'https://api.github.com/markdown/raw',
// headers: {
// accept: 'text/html;charset=utf-8',
// 'content-type': 'text/plain',
// 'user-agent': userAgent
// },
// body: 'Hello world github/linguist#1 **cool**, and #1!'
// }
//
// not as
//
// {
// ...
// body: '{"data": "Hello world github/linguist#1 **cool**, and #1!"}'
// }
```
### Set parameters for both the URL/query and the request body
There are API endpoints that accept both query parameters as well as a body. In that case you need to add the query parameters as templates to `options.url` , as defined in the [RFC 6570 URI Template specification ](https://tools.ietf.org/html/rfc6570 ).
Example
``` js
request (
"POST https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}" ,
{
name : "example.zip" ,
label : "short description" ,
headers : {
"content-type" : "text/plain" ,
"content-length" : 14 ,
2020-09-18 15:40:23 +01:00
authorization : ` token 0000000000000000000000000000000000000001 ` ,
2020-04-28 16:46:47 +02:00
} ,
2020-09-18 15:40:23 +01:00
data : "Hello, world!" ,
2025-03-14 13:13:56 -07:00
} ,
2020-04-28 16:46:47 +02:00
) ;
```
2025-03-14 13:13:56 -07:00
### Set a custom Agent to your requests
The way to pass a custom `Agent` to requests is by creating a custom `fetch` function and pass it as `options.request.fetch` . A good example can be [undici's `fetch` implementation ](https://undici.nodejs.org/#/?id=undicifetchinput-init-promise ).
Example ([See example in CodeSandbox ](https://codesandbox.io/p/sandbox/nifty-stitch-wdlwlf ))
``` js
import { request } from "@octokit/request" ;
import { fetch as undiciFetch , Agent } from "undici" ;
/** @type {typeof import("undici").fetch} */
const myFetch = ( url , options ) => {
return undiciFetch ( url , {
... options ,
dispatcher : new Agent ( {
keepAliveTimeout : 10 ,
keepAliveMaxTimeout : 10 ,
} ) ,
} ) ;
} ;
const { data } = await request ( "GET /users/{username}" , {
username : "octocat" ,
headers : {
"X-GitHub-Api-Version" : "2022-11-28" ,
} ,
options : {
request : {
fetch : myFetch ,
} ,
} ,
} ) ;
```
2020-04-28 16:46:47 +02:00
## LICENSE
[MIT ](LICENSE )