Skip to main content

Resources in the REST API

Learn how to navigate the resources provided by the GitHub API.

API version

Available resources may vary between REST API versions. You should use the X-GitHub-Api-Version header to specify an API version. For more information, see "API Versions."

Schema

All API access is over HTTPS, and accessed from https://api.github.com. All data is sent and received as JSON.

$ curl -I https://api.github.com/users/octocat/orgs

> HTTP/2 200
> Server: nginx
> Date: Fri, 12 Oct 2012 23:33:14 GMT
> Content-Type: application/json; charset=utf-8
> ETag: "a00049ba79152d03380c34652f2cb612"
> X-GitHub-Media-Type: github.v3
> x-ratelimit-limit: 5000
> x-ratelimit-remaining: 4987
> x-ratelimit-reset: 1350085394
> Content-Length: 5
> Cache-Control: max-age=0, private, must-revalidate
> X-Content-Type-Options: nosniff

Blank fields are included as null instead of being omitted.

All timestamps return in UTC time, ISO 8601 format:

YYYY-MM-DDTHH:MM:SSZ

For more information about timezones in timestamps, see this section.

Summary representations

When you fetch a list of resources, the response includes a subset of the attributes for that resource. This is the "summary" representation of the resource. (Some attributes are computationally expensive for the API to provide. For performance reasons, the summary representation excludes those attributes. To obtain those attributes, fetch the "detailed" representation.)

Example: When you get a list of repositories, you get the summary representation of each repository. Here, we fetch the list of repositories owned by the octokit organization:

GET /orgs/octokit/repos

Detailed representations

When you fetch an individual resource, the response typically includes all attributes for that resource. This is the "detailed" representation of the resource. (Note that authorization sometimes influences the amount of detail included in the representation.)

Example: When you get an individual repository, you get the detailed representation of the repository. Here, we fetch the octokit/octokit.rb repository:

GET /repos/octokit/octokit.rb

The documentation provides an example response for each API method. The example response illustrates all attributes that are returned by that method.

Authentication

GitHub recommends that you create a token to authenticate to the REST API. For more information about which type of token to create, see "Authenticating to the REST API."

You can authenticate your request by sending a token in the Authorization header of your request:

curl --request GET \
--url "https://api.github.com/octocat" \
--header "Authorization: Bearer YOUR-TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28"

Note: In most cases, you can use Authorization: Bearer or Authorization: token to pass a token. However, if you are passing a JSON web token (JWT), you must use Authorization: Bearer.

If you try to use a REST API endpoint without a token or with a token that has insufficient permissions, you will receive a 404 Not Found or 403 Forbidden response.

OAuth2 key/secret

Deprecation Notice: GitHub will discontinue authentication to the API using query parameters. Authenticating to the API should be done with HTTP basic authentication. Using query parameters to authenticate to the API will no longer work on May 5, 2021. For more information, including scheduled brownouts, see the blog post.

curl -u my_client_id:my_client_secret 'https://api.github.com/user/repos'

Using your client_id and client_secret does not authenticate as a user, it will only identify your OAuth app to increase your rate limit. Permissions are only granted to users, not applications, and you will only get back data that an unauthenticated user would see. Don't leak your OAuth app's client secret to your users.

For more information about rate limits for OAuth apps, see "Rate limits for the REST API."

Failed login limit

Authenticating with invalid credentials will return 401 Unauthorized:

$ curl -I https://api.github.com --header "Authorization: Bearer INVALID-TOKEN"
> HTTP/2 401

> {
>   "message": "Bad credentials",
>   "documentation_url": "https://docs.github.com/rest"
> }

After detecting several requests with invalid credentials within a short period, the API will temporarily reject all authentication attempts for that user (including ones with valid credentials) with 403 Forbidden:

> HTTP/2 403
> {
>   "message": "Maximum number of login attempts exceeded. Please try again later.",
>   "documentation_url": "https://docs.github.com/rest"
> }

Parameters

Many API methods take optional parameters. For GET requests, any parameters not specified as a segment in the path can be passed as an HTTP query string parameter:

curl -i "https://api.github.com/repos/vmg/redcarpet/issues?state=closed"

In this example, the 'vmg' and 'redcarpet' values are provided for the :owner and :repo parameters in the path while :state is passed in the query string.

For POST, PATCH, PUT, and DELETE requests, parameters not included in the URL should be encoded as JSON with a Content-Type of 'application/json':

curl -i --header "Authorization: Bearer YOUR-TOKEN" -d '{"scopes":["repo_deployment"]}' https://api.github.com/authorizations

Root endpoint

You can issue a GET request to the root endpoint to get all the endpoint categories that the REST API supports:

$ curl 
-u USERNAME:TOKEN https://api.github.com

GraphQL global node IDs

See the guide on "Using global node IDs" for detailed information about how to find node_ids via the REST API and use them in GraphQL operations.

HTTP verbs

Where possible, the GitHub REST API strives to use appropriate HTTP verbs for each action. Note that HTTP verbs are case-sensitive.

VerbDescription
HEADCan be issued against any resource to get just the HTTP header info.
GETUsed for retrieving resources.
POSTUsed for creating resources.
PATCHUsed for updating resources with partial JSON data. For instance, an Issue resource has title and body attributes. A PATCH request may accept one or more of the attributes to update the resource.
PUTUsed for replacing resources or collections. For PUT requests with no body attribute, be sure to set the Content-Length header to zero.
DELETEUsed for deleting resources.

Hypermedia

All resources may have one or more *_url properties linking to other resources. These are meant to provide explicit URLs so that proper API clients don't need to construct URLs on their own. It is highly recommended that API clients use these. Doing so will make future upgrades of the API easier for developers. All URLs are expected to be proper RFC 6570 URI templates.

You can then expand these templates using something like the uri_template gem:

>> tmpl = URITemplate.new('/notifications{?since,all,participating}')
>> tmpl.expand
=> "/notifications"

>> tmpl.expand all: 1
=> "/notifications?all=1"

>> tmpl.expand all: 1, participating: 1
=> "/notifications?all=1&participating=1"

User agent required

All API requests MUST include a valid User-Agent header. Requests with no User-Agent header will be rejected. We request that you use your GitHub username, or the name of your application, for the User-Agent header value. This allows us to contact you if there are problems.

Here's an example:

User-Agent: Awesome-Octocat-App

curl sends a valid User-Agent header by default. If you provide an invalid User-Agent header via curl (or via an alternative client), you will receive a 403 Forbidden response:

$ curl -IH 'User-Agent: ' https://api.github.com/meta
> HTTP/1.0 403 Forbidden
> Connection: close
> Content-Type: text/html

> Request forbidden by administrative rules.
> Please make sure your request has a User-Agent header.
> Check  for other possible causes.

Cross origin resource sharing

The API supports Cross Origin Resource Sharing (CORS) for AJAX requests from any origin. You can read the CORS W3C Recommendation, or this intro from the HTML 5 Security Guide.

Here's a sample request sent from a browser hitting http://example.com:

$ curl -I https://api.github.com -H "Origin: http://example.com"
HTTP/2 302
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval

This is what the CORS preflight request looks like:

$ curl -I https://api.github.com -H "Origin: http://example.com" -X OPTIONS
HTTP/2 204
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-GitHub-OTP, X-Requested-With
Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Max-Age: 86400

JSON-P callbacks

You can send a ?callback parameter to any GET call to have the results wrapped in a JSON function. This is typically used when browsers want to embed GitHub content in web pages by getting around cross domain issues. The response includes the same data output as the regular API, plus the relevant HTTP Header information.

$ curl https://api.github.com?callback=foo

> /**/foo({
>   "meta": {
>     "status": 200,
>     "x-ratelimit-limit": "5000",
>     "x-ratelimit-remaining": "4966",
>     "x-ratelimit-reset": "1372700873",
>     "Link": [ // pagination headers and other links
>       ["https://api.github.com?page=2", {"rel": "next"}]
>     ]
>   },
>   "data": {
>     // the data
>   }
> })

You can write a JavaScript handler to process the callback. Here's a minimal example you can try out:

<html>
<head>
<script type="text/javascript">
function foo(response) {
  var meta = response.meta;
  var data = response.data;
  console.log(meta);
  console.log(data);
}

var script = document.createElement('script');
script.src = 'https://api.github.com?callback=foo';

document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>

<body>
  <p>Open up your browser's console.</p>
</body>
</html>

All of the headers are the same String value as the HTTP Headers with one notable exception: Link. Link headers are pre-parsed for you and come through as an array of [url, options] tuples.

A link that looks like this:

Link: <url1>; rel="next", <url2>; rel="foo"; bar="baz"

... will look like this in the Callback output:

{
  "Link": [
    [
      "url1",
      {
        "rel": "next"
      }
    ],
    [
      "url2",
      {
        "rel": "foo",
        "bar": "baz"
      }
    ]
  ]
}

Timezones

Some requests that create new data, such as creating a new commit, allow you to provide time zone information when specifying or generating timestamps. We apply the following rules, in order of priority, to determine timezone information for such API calls.

Note that these rules apply only to data passed to the API, not to data returned by the API. As mentioned in "Schema," timestamps returned by the API are in UTC time, ISO 8601 format.

Explicitly providing an ISO 8601 timestamp with timezone information

For API calls that allow for a timestamp to be specified, we use that exact timestamp. An example of this is the API to manage commits. For more information, see "Git database."

These timestamps look something like 2014-02-27T15:05:06+01:00. Also see this example for how these timestamps can be specified.

Using the Time-Zone header

It is possible to supply a Time-Zone header which defines a timezone according to the list of names from the Olson database.

curl -H "Time-Zone: Europe/Amsterdam" -X POST https://api.github.com/repos/github-linguist/linguist/contents/new_file.md

This means that we generate a timestamp for the moment your API call is made in the timezone this header defines. For example, the API to manage contents generates a git commit for each addition or change and uses the current time as the timestamp. For more information, see "Repositories." This header will determine the timezone used for generating that current timestamp.

Using the last known timezone for the user

If no Time-Zone header is specified and you make an authenticated call to the API, we use the last known timezone for the authenticated user. The last known timezone is updated whenever you browse the GitHub website.

Defaulting to UTC without other timezone information

If the steps above don't result in any information, we use UTC as the timezone to create the git commit.