Skip to main content

REST API 中的资源

了解如何导航 GitHub API 提供的资源。

API 版本

可用资源可能因不同的 REST API 版本而异。 应使用 X-GitHub-Api-Version 标头指定 API 版本。 有关详细信息,请参阅“API 版本”。

架构

所有 API 访问都通过 HTTPS 进行,并且 从 https://api.github.com 进行访问。 所有数据都以 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

空白字段包含为 null,而不是被省略。

所有时间戳以 ISO 8601 格式返回 UTC 时间:

YYYY-MM-DDTHH:MM:SSZ

有关时间戳中的时区的详细信息,请参阅本部分

摘要表示

提取资源列表时,响应包含该资源的属性子集。 这就是资源的“摘要”表示形式。 (对于某些属性,API 要经过大量计算后才可提供。 出于性能考虑,摘要表示排除了这些属性。 要获得这些属性,请获取“详细”表示。)

示例:在获取存储库列表时,会获取每个存储库的摘要表示形式。 在这里,我们提取 octokit 组织拥有的存储库列表:

GET /orgs/octokit/repos

详细表示

提取单个资源时,响应通常包含该资源的所有属性。 这就是资源的“详细”表示形式。 (请注意,授权有时会影响表示形式中包含的详细信息量。)

示例:在获取单个存储库时,会获取该存储库的详细表示形式。 在这里,我们提取 octokit/octokit.rb 存储库:

GET /repos/octokit/octokit.rb

本文档提供每种 API 方法的示例响应。 示例响应说明了该方法返回的所有属性。

身份验证

GitHub 建议创建令牌来对 REST API 进行身份验证。 有关要创建的令牌类型的详细信息,请参阅“对 REST API 进行身份验证”。

你可以通过在请求的 Authorization 标头中发送令牌来对请求进行身份验证:

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

注意:在大多数情况下,可以使用 Authorization: BearerAuthorization: token 传递令牌。 但是,如果要传递 JSON Web 令牌 (JWT),则必须使用 Authorization: Bearer

如果尝试在没有令牌或令牌权限不足的情况下使用 REST API 终结点,你将收到 404 Not Found403 Forbidden 响应。

OAuth2 键/密钥

弃用通知:GitHub 将停止使用查询参数对 API 进行身份验证。 应使用 HTTP 基本身份验证对 API 进行身份验证。 自 2021 年 5 月 5 日起,使用查询参数对 API 进行身份验证将不再有效。 有关详细信息,包括计划限电,请参阅博客文章

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

使用 client_idclient_secret 不会以用户身份进行身份验证,它只会识别 OAuth app 以增加速率限制。 权限仅授予用户,而不授予应用程序,因此只会返回未经验证用户可以看到的数据。 不要向用户泄露 OAuth app 的客户端密码。

阅读有关未经身份验证的速率限制的详细信息

失败登录限制

使用无效凭据进行身份验证将返回 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"
> }

在短时间内检测到多个使用无效凭据的请求后,API 将暂时拒绝该用户的所有身份验证尝试(包括使用有效凭据的尝试),并返回 403 Forbidden

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

参数

许多 API 方法采用可选参数。 对于 GET 请求,路径中任何未指定为段的参数都可以作为 HTTP 查询字符串参数进行传递:

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

在此示例中,在查询字符串中传递 :state 时,为路径中的 :owner:repo 参数提供“vmg”和“redcarpet”值。

对于 POSTPATCHPUTDELETE 请求,未包含在 URL 中的参数应编码为 JSON,内容类型为“application/json”:

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

根终结点

可以向根终结点发出 GET 请求,以获取 REST API 支持的所有终结点类别:

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

GraphQL 全局节点 ID

有关如何通过 REST API 查找 node_id 并在 GraphQL 操作中使用它们的详细信息,请参阅有关“使用全局节点 ID”的指南。

客户端错误

接收请求正文的 API 调用上可能存在三种类型的客户端错误:

  1. 发送无效的 JSON 将导致 400 Bad Request 响应。

     HTTP/2 400
     Content-Length: 35
    
     {"message":"Problems parsing JSON"}
    
  2. 发送错误类型的 JSON 值将导致 400 Bad Request 响应。

     HTTP/2 400
     Content-Length: 40
    
     {"message":"Body should be a JSON object"}
    
  3. 发送无效字段将导致 422 Unprocessable Entity 响应。

     HTTP/2 422
     Content-Length: 149
    
     {
       "message": "Validation Failed",
       "errors": [
         {
           "resource": "Issue",
           "field": "title",
           "code": "missing_field"
         }
       ]
     }
    

所有错误对象都具有资源和字段属性,以便客户端可以知道问题所在。 还有一个错误代码,让你知道该字段有什么问题。

错误代码说明
missing资源不存在。
missing_field资源上的必需字段尚未设置。
invalid字段的格式无效。 请查看文档以了解更具体的信息。
already_exists另一个资源具有与此字段相同的值。 在必须具有某些唯一键(例如标签名称)的资源中可能会发生这种情况。
unprocessable提供的输入无效。

资源还可能发送自定义验证错误(其中 codecustom)。 自定义错误将始终包含一个描述错误的 message 字段,大多数错误还将包括一个 documentation_url 字段,该字段指向可能有助于解决错误的某些内容。

HTTP 重定向

GitHub 在适当情况下使用 HTTP 重定向。 客户端应假定任何请求都可能会导致重定向。 接收 HTTP 重定向不是错误,客户端应遵循该重定向。 重定向响应将包含一个 Location 标头字段,其中包含客户端应重复请求的资源的 URI。

301 状态代码指示永久重定向。 用于发出请求的 URI 已被 Location 标头字段中指定的 URI 所取代。 此请求以及对此资源的所有未来请求都应定向到新的 URI。

302307 状态代码指示临时重定向。 请求应按 Location 标头字段中指定的 URI 逐字重复,但客户端应对未来的请求继续使用原来的 URI。

其他重定向状态代码可根据 HTTP 1.1 规范使用。

HTTP 谓词

在可能的情况下,GitHub REST API 尽量为每个操作使用适当的 Http 谓词。 请注意,HTTP 谓词区分大小写。

谓词说明
HEAD可以针对任何资源发出以仅获取 HTTP 标头信息。
GET用于检索资源。
POST用于创建资源。
PATCH用于通过部分 JSON 数据更新资源。 例如,问题资源具有 titlebody 属性。 PATCH 请求可以接受一个或多个属性来更新资源。
PUT用于替换资源或集合。 对于没有 body 属性的 PUT 请求,请确保将 Content-Length 标头设置为零。
DELETE用于删除资源。

超媒体

所有资源都可以具有一个或多个链接到其他资源的 *_url 属性。 这些属性旨在提供明确的 URL,使适当的 API 客户端不需要自己构建 URL。 强烈建议 API 客户端使用这些属性。 这样做有助于开发者未来更容易升级 API。 所有 URL 都应该是适当的 RFC 6570 URI 模板。

然后,可以使用 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"

超时

如果 GitHub 处理 API 请求的时间超过 10 秒,GitHub 将终止请求,你将收到如下所示的超时响应:

{
    "message": "Server Error"
}

GitHub 保留更改超时窗口的权利,以保护 API 的速度和可靠性。

速率限制

GitHub REST API 使用速率限制来控制 API 流量。 不同类型的 API 请求具有不同的速率限制。 响应头描述当前的速率限制状态。

速率限制

对 GitHub.com 的不同类型的 API 请求遵循不同的费率限制。 此外,搜索终结点具有专门的限制。 有关详细信息,请参阅 REST API 文档中的“搜索”。

来自个人帐户的请求的速率限制

可以发出使用 personal access token 进行身份验证的直接 API 请求。 在授权应用后,OAuth app 或 GitHub App 也可以代表你发出请求。 有关详细信息,请参阅“管理个人访问令牌”、“授权 OAuth 应用”和“授权 GitHub Apps”。

GitHub 可将所有这些请求与经过身份验证的用户相关联。 对于 OAuth apps 和 GitHub Apps,这是授权应用的用户。 所有这些请求都会计入经过身份验证的用户的速率限制。

用户访问令牌请求的速率限制为每个经验证的用户每小时最多发送 5,000 个请求。 来自用户授权的 OAuth apps 或用户拥有的 personal access token 的所有请求,以及使用用户的任何身份验证凭据进行身份验证的请求,都共享该用户每小时 5,000 个请求的相同配额。

在以下情况下,用户访问令牌请求限制为每小时每个经身份验证的用户最多发送 15,000 个请求:

  • 请求来自由 GitHub Enterprise Cloud 组织拥有的 GitHub App。
  • 请求来自由 GitHub Enterprise Cloud 组织拥有或批准的 OAuth app。

对于未经验证的请求,速率限制允许每小时最多 60 个请求。 未经验证的请求与原始 IP 地址相关联,与发出请求的个人无关。

来自 GitHub Apps 的请求的速率限制

GitHub App 的请求可以使用用户访问令牌或安装访问令牌。 有关 GitHub Apps 的速率限制的详细信息,请参阅“GitHub 应用的速率限制”。

来自 GitHub Actions 的请求的速率限制

可以使用内置的 GITHUB_TOKEN 来验证 GitHub Actions 工作流中的请求。 有关详细信息,请参阅“自动令牌身份验证”。

使用 GITHUB_TOKEN 时,速率限制为每个存储库每小时 1,000 个请求。 如果请求属于 GitHub.com 上的企业帐户的资源,GitHub Enterprise Cloud 的速率限制适用,并且限制为每个存储库每小时 15,000 个请求。

检查您的速率限制状态

响应头描述当前的速率限制状态。 还可以使用 REST API 查找你或你的应用在任何给定时间可以使用的当前 API 调用数。

速率限制标头

x-ratelimit 响应头描述每次请求后的当前速率限制状态:

$ curl -i https://api.github.com/users/octocat
> HTTP/2 200
> x-ratelimit-limit: 60
> x-ratelimit-remaining: 56
> x-ratelimit-used: 4
> x-ratelimit-reset: 1372700873
标头名称说明
x-ratelimit-limit每小时允许您发出的最大请求数。
x-ratelimit-remaining当前速率限制窗口中剩余的请求数。
x-ratelimit-used当前速率限制窗口中已发出的请求数。
x-ratelimit-reset当前速率限制窗口重置的时间,单位为 UTC 纪元秒

使用 REST API 检查速率限制状态

可以使用 REST API 检查速率限制状态,而不会对当前限制造成影响。 有关详细信息,请参阅“速率限制”。 如果可能,GitHub 建议改用 x-ratelimit 响应头,以减少 API 上的负载。

超出速率限制

如果超出速率限制,响应将具有 403 状态并且 x-ratelimit-remaining 标头将为 0

> HTTP/2 403
> Date: Tue, 20 Aug 2013 14:50:41 GMT
> x-ratelimit-limit: 60
> x-ratelimit-remaining: 0
> x-ratelimit-used: 60
> x-ratelimit-reset: 1377013266

> {
>    "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
>    "documentation_url": "https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting"
> }

对于使用 Git LFS API 的请求(即 Git LFS 客户端使用的请求),响应将改为具有 429 状态。

如果速率受限,则在 x-ratelimit-reset 时间所指定的时间之前,不应尝试请求。

提高 OAuth apps 的未经身份验证的速率限制

如果 OAuth app 需要以更高的速率限制对公共资源进行未经身份验证的调用,你可以在终结点路由之前传递应用的客户端 ID 和机密。

$ curl -u my_client_id:my_client_secret -I https://api.github.com/meta
> HTTP/2 200
> Date: Mon, 01 Jul 2013 17:27:06 GMT
> x-ratelimit-limit: 5000
> x-ratelimit-remaining: 4966
> x-ratelimit-used: 34
> x-ratelimit-reset: 1372700873

注意:切勿与任何人共享客户端密码,也不要将其包含在客户端浏览器代码中。

保持在速率限制之内

如果使用基本身份验证或 OAuth 时超出了速率限制,则可以通过缓存 API 响应和使用条件请求来解决此问题。

二级费率限制

上述速率限制适用于整个 REST API,并且针对每个用户或每个应用。 为了在 GitHub 上提供优质的服务,使用 API 时,某些操作可能会受到额外的速率限制。 例如,使用 API 快速创建内容、主动轮询而不是使用 web 挂钩、发出多个并发请求或重复请求计算成本高昂的数据,可能会导致其他速率限制。

其他速率限制无意干扰 API 的合法使用。 您的正常速率限制应该是您目标的唯一限制。 为了确保成为 API 好公民,请查看最佳做法指南

如果应用程序触发其他速率限制,你将收到信息响应:

> HTTP/2 403
> Content-Type: application/json; charset=utf-8
> Connection: close

> {
>   "message": "You have exceeded a secondary rate limit and have been temporarily blocked from content creation. Please retry your request again later.",
>   "documentation_url": "https://docs.github.com/rest/overview/resources-in-the-rest-api#secondary-rate-limits"
> }

应等待,稍后再尝试发出请求。 如果有 retry-after 响应头,则应先等待数秒,然后再尝试请求。 如果 x-ratelimit-remaining 标头为 0,应在 x-ratelimit-reset 标头所指定的时间(以 UTC 新纪元时间秒为单位)之后,再尝试发出请求。 否则,请在两次重试之间等待一段呈指数级增长的时间,并在重试特定次数后引发错误。

必需用户代理

所有 API 请求都必须包含有效的 User-Agent 标头。 没有 User-Agent 标头的请求将被拒绝。 我们要求你使用 GitHub 用户名或应用程序的名称作为 User-Agent 标头值。 这是为了方便我们在发现问题时与您联系 。

下面是一个示例:

User-Agent: Awesome-Octocat-App

默认情况下,curl 发送有效的 User-Agent 标头。 如果通过 curl(或通过备用客户端)提供无效的 User-Agent 标头,则将收到 403 Forbidden 响应:

$ 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.

条件请求

大多数响应都返回 ETag 标头。 许多响应还返回 Last-Modified 标头。 可以使用这些标头的值分别使用 If-None-MatchIf-Modified-Since 标头向这些资源发出后续请求。 如果资源未发生更改,服务器将返回 304 Not Modified

注意:发出条件请求并收到 304 响应不计入速率限制,因此我们鼓励你尽可能地使用它。

$ curl -I https://api.github.com/user
> HTTP/2 200
> Cache-Control: private, max-age=60
> ETag: "644b5b0155e6404a9cc4bd9d8b1ae730"
> Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
> Vary: Accept, Authorization, Cookie
> x-ratelimit-limit: 5000
> x-ratelimit-remaining: 4996
> x-ratelimit-reset: 1372700873

$ curl -I https://api.github.com/user -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"'
> HTTP/2 304
> Cache-Control: private, max-age=60
> ETag: "644b5b0155e6404a9cc4bd9d8b1ae730"
> Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
> Vary: Accept, Authorization, Cookie
> x-ratelimit-limit: 5000
> x-ratelimit-remaining: 4996
> x-ratelimit-reset: 1372700873

$ curl -I https://api.github.com/user -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT"
> HTTP/2 304
> Cache-Control: private, max-age=60
> Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT
> Vary: Accept, Authorization, Cookie
> x-ratelimit-limit: 5000
> x-ratelimit-remaining: 4996
> x-ratelimit-reset: 1372700873

跨源资源共享

API 支持来自任何源的 AJAX 请求的跨源资源共享 (CORS)。 可以阅读 CORS W3C 建议,或 HTML 5 安全指南中的此简介

下面是从浏览器点击 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

以下是 CORS 预检请求的示例:

$ 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 回调

可以向任何 GET 调用发送 ?callback 参数,以便将结果包装在 JSON 函数中。 当浏览器希望绕开跨域问题将 GitHub 内容嵌入网页时,通常使用此方法。 响应包括与常规 API 相同的数据输出,加上相关的 HTTP 标头信息。

$ 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
>   }
> })

您可以编写一个 JavaScript 处理程序来处理回调。 以下是一个最小的处理程序示例,您可以尝试编写:

<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>

所有标头都具有与 HTTP 标头相同的字符串值,但有一个值得注意的例外:链接。 链接标头已预先解析,并以 [url, options] 元组的数组形式出现。

链接如下所示:

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

... 在回调输出中将如下所示:

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

时区

某些创建新数据的请求(例如创建新的提交)允许您在指定或生成时间戳时提供时区信息。 我们按照优先顺序应用以下规则来确定这些 API 调用的时区信息。

请注意,这些规则仅适用于传递给 API 的数据,而不适用于 API 返回的数据。 如“架构”中所述,API 返回的时间戳采用 UTC 时间、ISO 8601 格式。

明确提供带有时区信息的 ISO 8601 时间戳

对于允许指定时间戳的 API 调用,我们使用这种明确的时间戳。 其中一个示例是用于管理提交的 API。 有关详细信息,请参阅“Git 数据库”。

这些时间戳类似于 2014-02-27T15:05:06+01:00。 如需了解如何指定这些时间戳,另请参阅此示例

使用 Time-Zone 标头

可以提供一个 Time-Zone 标头,该标头根据 Olson 数据库中的名称列表定义时区。

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

这意味着当您在这个标题定义的时区做出 API 调用时,我们会生成一个时间戳。 例如,用于管理内容的 API 会为每个添加或更改生成 git 提交,并使用当前时间作为时间戳。 有关详细信息,请参阅“存储库”。 此标头将确定用于生成当前时间戳的时区。

使用用户的最后一个已知时区

如果未指定 Time-Zone 标头,并且你对 API 进行经过身份验证的调用,则我们对经过身份验证的用户使用最后一个已知时区。 最新一个已知的时区在您浏览 GitHub 网站时都会更新。

在没有其他时区信息的情况下默认使用 UTC

如果上述步骤未产生任何信息,我们将使用 UTC 作为时区来创建 git 提交。