octokit/rest.js

Usage

Import the Octokit constructor based on your platform.

Browsers

Load @octokit/rest directly from cdn.skypack.dev
<script type="module">
  import { Octokit } from "https://cdn.skypack.dev/@octokit/rest";
</script>

Node

Install with npm install @octokit/rest
const { Octokit } = require("@octokit/rest");
// or: import { Octokit } from "@octokit/rest";

const { Octokit } = require("@octokit/rest");

Now instantiate your octokit API. All options are optional, but authentication is strongly encouraged.

const octokit = new Octokit({

You can set auth to a personal access token string.

Learn more about authentication.

  auth: "secret123",

Setting a user agent is required. It defaults to octokit/rest.js v1.2.3 where v1.2.3 is the current version of @octokit/rest, but you should set it to something that identifies your app or script.

  userAgent: 'myApp v1.2.3',

API Previews can be enabled globally by setting the previews option. They can be set per-request as well.

Learn more about API Previews.

  previews: ['jean-grey', 'symmetra'],

A default time zone can be enabled by setting the timeZone option.

  timeZone: 'Europe/Amsterdam',

Learn more about using time zones with the GitHub API.

In order to use Octokit with GitHub Enterprise, set the baseUrl option.

  baseUrl: 'https://api.github.com',

For custom logging, pass an object with debug, info, warn and error methods as the log option.

Learn more about logging and debugging.

  log: {
    debug: () => {},
    info: () => {},
    warn: console.warn,
    error: console.error
  },

Custom request options can be passed as request.* options. See @octokit/request options. The same options can be passed to each endpoint request method.

  request: {
    agent: undefined,
    fetch: undefined,
    timeout: 0
  }
})

Most of GitHub’s REST API endpoints have matching methods. All endpoint methods are asynchronous, in order to use await in the code examples, we wrap them into an anonymous async function.

(async () => {

For example to retrieve a pull request, use octokit.rest.pulls.get(). We recommend to use the search above to find the endpoint method you are looking for

const { data: pullRequest } = await octokit.rest.pulls.get({
  owner: "octokit",
  repo: "rest.js",
  pull_number: 123,
});

Some API endpoints support alternative response formats, see Media types. For example, to request the above pull request in a diff format, pass the mediaType.format option.

Learn more about request formats.

const { data: diff } = await octokit.rest.pulls.get({
  owner: "octokit",
  repo: "rest.js",
  pull_number: 123,
  mediaType: {
    format: "diff",
  },
});

For the API endpoints that do not have a matching method, such as the root endpoint or legacy endpoints, you can send custom requests.

Learn more about custom requests.

const { data: root } = await octokit.request("GET /");

You can also register custom endpoint methods, which is particularly useful if you participate in a private beta.

Learn more about custom endpoint methods.

await octokit.registerEndpoints({
  misc: {
    getRoot: {
      method: "GET",
      url: "/",
    },
  },
});

Some endpoints return a list which has to be paginated in order to retrieve the complete data set.

Learn more about pagination.

  octokit.paginate(octokit.rest.issues.listForRepo, {
    owner: 'octokit',
    repo: 'rest.js'
  })
    .then(issues => {
      // issues is an array of all issue objects
    })
})

You can add more functionality with plugins. We recommend the retry and throttling plugins.

Learn more about throttling, automatic retries and building your own Plugins.

import { retry } from "@octokit/plugin-retry";
import { throttling } from "@octokit/plugin-throttling";

const MyOctokit = Octokit.plugin(retry, throttling);

Octokit.plugin() returns a new constructor. The same options can be passed to the constructor. The options are passed on to all plugin functions as the 2nd argument.

const myOctokit = new MyOctokit({
  auth: "secret123",
  throttle: {
    onRateLimit: (retryAfter, options) => {
      myOctokit.log.warn(
        `Request quota exhausted for request ${options.method} ${options.url}`
      );

      if (options.request.retryCount === 0) {
        // only retries once
        myOctokit.log.info(`Retrying after ${retryAfter} seconds!`);
        return true;
      }
    },
    onSecondaryRateLimit: (retryAfter, options, octokit) => {
      // does not retry, only logs a warning
      octokit.log.warn(
        `Secondary quota detected for request ${options.method} ${options.url}`
      );
    },
  },
  retry: {
    doNotRetry: ["429"],
  },
});

Authentication

Authentication is optional for some REST API endpoints accessing public data, but is required for GraphQL queries. Using authentication also increases your API rate limit.

GitHub supports different authentication strategies:

  1. Personal access token (create). This is the default authentication strategy. Set the options.auth option to the token in new Octokit(options). Learn more about the built-in @octokit/auth-token authentication strategy.
  2. OAuth Apps: authenticate using user access token created by an OAuth app, to which you granted selected permissions, or as the OAuth App itself (OAuth using client_id and client_secret). Learn more about the optional @octokit/auth-oauth-app authentication strategy
  3. GitHub Apps: authenticate using an installation access token or as GitHub App itself. Learn more about the optional @octokit/auth-app authentication strategy.
  4. GitHub Actions: authenticate using the GITHUB_TOKEN secret which is provided to GitHub Actions Workflows. Learn more about the optional @octokit/auth-action authentication strategy.

Learn more about all official and community authentication strategies.

By default, @octokit/rest authenticates using the token authentication strategy. Pass in a token using options.auth. It can be a personal access token, an OAuth token, an installation access token or a JSON Web Token for GitHub App authentication. The Authorization request header will be set according to the type of token.

const { Octokit } = require("@octokit/rest");

const octokit = new Octokit({
  auth: "mypersonalaccesstoken123",
});

// sends request with `Authorization: token mypersonalaccesstoken123` header
const { data } = await octokit.request("/user");

To use a different authentication strategy, set options.authStrategy. Here is an example for GitHub App authentication

const { Octokit } = require("@octokit/rest");
const { createAppAuth } = require("@octokit/auth-app");

const appOctokit = new Octokit({
  authStrategy: createAppAuth,
  auth: {
    appId: 123,
    privateKey: process.env.PRIVATE_KEY,
    // optional: this will make appOctokit authenticate as app (JWT)
    //           or installation (access token), depending on the request URL
    installationId: 123,
  },
});

const { data } = await appOctokit.request("/app");

The .auth() method returned by the current authentication strategy can be accessed at octokit.auth(). Example

const { token } = await appOctokit.auth({
  type: "installation",
  // defaults to `options.auth.installationId` set in the constructor
  installationId: 123,
});

Previews

To enable any of GitHub’s API Previews, pass the previews option to the GitHub constructor

const octokit = new Octokit({
  previews: ["mercy-preview"],
});

Previews can also be enabled for a single request by passing the mediaType.preview option

const {
  data: { topics },
} = await octokit.rest.repos.get({
  owner: "octokit",
  repo: "rest.js",
  mediaType: {
    previews: ["symmetra"],
  },
});

Request formats & aborts

Some API endpoints support alternative response formats, see Media types.

For example, to request a pull request as diff format, set the mediaType.format option

const { data: prDiff } = await octokit.rest.pulls.get({
  owner: "octokit",
  repo: "rest.js",
  pull_number: 1278,
  mediaType: {
    format: "diff",
  },
});

The AbortController interface can be used to abort one or more requests as and when desired. When the request is initiated, an AbortSignal instance can be passed as an option inside the request's options object. For usage in Node, the abort-controller package can be used.

const controller = new AbortController();
const { data: prDiff } = await octokit.rest.pulls.get({
  owner: "octokit",
  repo: "rest.js",
  pull_number: 1278,
  request: {
    signal: controller.signal,
  },
});

Use controller.abort() to abort the request when desired.

Custom requests

To send custom requests you can use the lower-level octokit.request() method

octokit.request("GET /");

The baseUrl, headers and other defaults are already set. For more information on the octokit.request() API see octokit/request.js

All the endpoint methods such as octokit.rest.repos.get() are aliases of octokit.request() with pre-bound default options. So you can use the @octokit/request API to get the default options or get generic request option to use with your preferred request library.

const defaultOptions = octokit.rest.repos.get.endpoint.DEFAULTS;
const requestOptions = octokit.rest.repos.get.endpoint({
  owner: "octokit",
  repo: "rest.js",
});

Note that authentication is not applied when retrieving request options from the *.endpoint APIs.

Pagination

All endpoint methods starting with .list* do not return all results at once but instead return the first 30 items by default, see also GitHub’s REST API pagination documentation.

To automatically receive all results across all pages, you can use the octokit.paginate() method:

octokit
  .paginate("GET /repos/{owner}/{repo}/issues", {
    owner: "octokit",
    repo: "rest.js",
  })
  .then((issues) => {
    // issues is an array of all issue objects. It is not wrapped in a { data, headers, status, url } object
    // like results from `octokit.request()` or any of the endpoint methods such as `octokit.rest.issues.listForRepo()`
  });

octokit.paginate() accepts the same options as octokit.request(). You can optionally pass an additional function to map the results from each response. The map must return a new value, usually an array with mapped data.

Note: the map function is called with the { data, headers, status, url } response object. The data property is guaranteed to be an array of the result items, even for list endpoints that respond with an object instead of an array, such as the search endpoints.

octokit
  .paginate(
    "GET /repos/{owner}/{repo}/issues",
    { owner: "octokit", repo: "rest.js" },
    (response) => response.data.map((issue) => issue.title)
  )
  .then((issueTitles) => {
    // issueTitles is now an array with the titles only
  });

To stop paginating early, you can call the done() function passed as 2nd argument to the response map function. Note that you still have to return the value you want to map the response to, otherwise the last response will be mapped to undefined.

octokit.paginate(
  "GET /repos/{owner}/{repo}/issues",
  { owner: "octokit", repo: "rest.js" },
  (response, done) => {
    if (response.data.find((issue) => issue.body.includes("something"))) {
      done();
    }
    return response.data;
  }
);

To paginate responses for one of the registered endpoint methods such as octokit.rest.issues.listForRepo() you can pass the method directly as first argument to octokit.paginate:

octokit
  .paginate(octokit.rest.issues.listForRepo, {
    owner: "octokit",
    repo: "rest.js",
  })
  .then((issues) => {
    // issues is an array of all issue objects
  });

If your runtime environment supports async iterators (such as most modern browsers and Node 10+), you can iterate through each response

for await (const response of octokit.paginate.iterator(
  octokit.rest.issues.listForRepo,
  {
    owner: "octokit",
    repo: "rest.js",
  }
)) {
  // do whatever you want with each response, break out of the loop, etc.
}

octokit.paginate.iterator() accepts the same options as octokit.paginate().

Hooks

You can customize Octokit’s request lifecycle with hooks. Available methods are

octokit.hook.before("request", async (options) => {
  validate(options);
});
octokit.hook.after("request", async (response, options) => {
  console.log(`${options.method} ${options.url}: ${response.status}`);
});
octokit.hook.error("request", async (error, options) => {
  if (error.status === 304) {
    return findInCache(error.response.headers.etag);
  }

  throw error;
});
octokit.hook.wrap("request", async (request, options) => {
  // add logic before, after, catch errors or replace the request altogether
  return request(options);
});

See before-after-hook for more details on the 4 methods.

Custom endpoint methods

Note: octokit.registerEndpoints() has been deprecated.

Instead of

await octokit.registerEndpoints({
  misc: {
    getRoot: {
      method: "GET",
      url: "/",
    },
  },
});

do

Object.assign(octokit.misc, {
  getRoot: octokit.request.defaults({
    method: "GET",
    url: "/",
  }),
});

If you use octokit.registerEndpoints() in a plugin, return an object instead:

function myPlugin(octokit, options) {
  return {
    misc: {
      octokit.request.defaults({ method: "GET", url: "/" })
    }
  }
}

You can register custom endpoint methods such as octokit.rest.repos.get() using the octokit.registerEndpoints(routes) method

octokit.registerEndpoints({
  foo: {
    bar: {
      method: "PATCH",
      url: "/repos/{owner}/{repo}/foo",
      headers: {
        accept: "application/vnd.github.foo-bar-preview+json",
      },
      params: {
        owner: {
          required: true,
          type: "string",
        },
        repo: {
          required: true,
          type: "string",
        },
        baz: {
          required: true,
          type: "string",
          enum: ["qux", "quux", "quuz"],
        },
      },
    },
  },
});

octokit.foo.bar({
  owner: "octokit",
  repo: "rest.js",
  baz: "quz",
});

This is useful when you participate in private beta features and prefer the convenience of methods for the new endpoints instead of using octokit.request().

Plugins

You can customize and extend Octokit’s functionality using plugins

// index.js
const { Octokit } = require("@octokit/rest");
const MyOctokit = Octokit.plugin(
  require("./lib/my-plugin"),
  require("octokit-plugin-example")
);

// lib/my-plugin.js
module.exports = (octokit, options = { greeting: "Hello" }) => {
  // hook into the request lifecycle
  octokit.hook.wrap("request", async (request, options) => {
    const time = Date.now();
    const response = await request(options);
    octokit.log.info(
      `${options.method} ${options.url}${response.status} in ${
        Date.now() - time
      }ms`
    );
    return response;
  });

  // add a custom method: octokit.helloWorld()
  return {
    helloWorld: () => console.log(`${options.greeting}, world!`),
  };
};

.plugin accepts a function or an array of functions.

We recommend using Octokit’s log methods to help users of your plugin with debugging.

You can add new methods to the octokit instance passed as the first argument to the plugin function. The 2nd argument is the options object passed to the constructor when instantiating the octokit client.

const octokit = new MyOctokit({ greeting: "Hola" });
octokit.helloWorld();
// Hola, world!

Throttling

When you send too many requests in too little time you will likely hit errors due to rate and/or abuse limits.

In order to automatically throttle requests as recommended in GitHub’s best practices for integrators, we recommend you install the @octokit/plugin-throttling plugin.

The throttle.onSecondaryRateLimit and throttle.onRateLimit options are required.

Return true from these functions to automatically retry the request after retryAfter seconds. Return false or undefined to skip retry and throw the error. For rate limit errors, retryAfter defaults to seconds until X-RateLimit-Reset. For abuse errors, retryAfter defaults to the retry-after header but is a minimum of five seconds.

const { Octokit } = require("@octokit/rest");
const { throttling } = require("@octokit/plugin-throttling");
const MyOctokit = Octokit.plugin(throttling);

const octokit = new MyOctokit({
  auth: "token " + process.env.TOKEN,
  throttle: {
    onRateLimit: (retryAfter, options) => {
      octokit.log.warn(
        `Request quota exhausted for request ${options.method} ${options.url}`
      );

      // Retry twice after hitting a rate limit error, then give up
      if (options.request.retryCount <= 2) {
        console.log(`Retrying after ${retryAfter} seconds!`);
        return true;
      }
    },
    onSecondaryRateLimit: (retryAfter, options, octokit) => {
      // does not retry, only logs a warning
      octokit.log.warn(
        `Secondary quota detected for request ${options.method} ${options.url}`
      );
    },
  },
});

Automatic retries

Many common request errors can be easily remediated by retrying the request. We recommend installing the @octokit/plugin-retry plugin for Automatic retries in these cases

const { Octokit } = require("@octokit/rest");
const { retry } = require("@octokit/plugin-retry");
const MyOctokit = Octokit.plugin(retry);

const octokit = new MyOctokit();

// all requests sent with the `octokit` instance are now retried up to 3 times for recoverable errors.

Logging

Octokit has 4 built-in log methods

  1. octokit.log.debug(message[, additionalInfo])
  2. octokit.log.info(message[, additionalInfo])
  3. octokit.log.warn(message[, additionalInfo])
  4. octokit.log.error(message[, additionalInfo])

They can be configured using the log client option. By default, octokit.log.debug() and octokit.log.info() are no-ops, while the other two call console.warn() and console.error() respectively.

This is useful if you build reusable plugins.

Debug

The simplest way to receive debug information is to set the log client option to console.

const octokit = require("@octokit/rest")({
  log: console,
});

octokit.request("/");

This will log

request { method: 'GET',
  baseUrl: 'https://api.github.com',
  headers:
   { accept: 'application/vnd.github.v3+json',
     'user-agent':
      'octokit.js/0.0.0-development Node.js/10.15.0 (macOS Mojave; x64)' },
  request: {},
  url: '/' }
GET / - 200 in 514ms

If you like to support a configurable log level, we recommend using the console-log-level module

const octokit = require("@octokit/rest")({
  log: require("console-log-level")({ level: "info" }),
});

octokit.request("/");

This will only log

GET / - 200 in 514ms