github-api
GitHub REST API
GitHub REST API는 GitHub의 기능을 스크립트나 애플리케이션으로 자동화하고, GitHub에 통합하며, GitHub를 확장하는 데 사용하는 공식 API예요. 예를 들어 이슈를 분류(triage)하거나, 분석 대시보드를 만들거나, 릴리스를 관리하는 데 활용할 수 있어요. 각 REST API 엔드포인트는 개별적으로 문서화되어 있고, 주로 영향을 주는 리소스별로 분류되어 있답니다. 이슈와 관련된 엔드포인트는 REST API endpoints for issues에서 찾을 수 있어요.
본문
REST API란?
GitHub REST API는 HTTP 기반의 API로, 가지 리소스에 대해 GET, POST, PATCH, PUT, DELETE 같은 HTTP 메서드를 사용해 작업을 수행해요. 요청을 보낼 때는 다음 요소들이 포함돼요.
- HTTP 메서드: 리소스에 수행할 작업의 종류를 결정해요.
GET은 조회,POST는 생성,PATCH는 속성 수정,PUT은 교체,DELETE는 삭제에 사용해요. - 경로(Path): 각 엔드포인트의 경로예요. 예를 들어 "List repository issues" 엔드포인트의 경로는
/repos/{owner}/{repo}/issues예요. 중괄호{}는 경로 파라미터를 뜻하며, 요청 시 실제 값으로 바꿔줘야 해요. - 헤더(Headers): 요청에 대한 추가 정보를 담아요. 대부분의 엔드포인트는
Accept: application/vnd.github+json헤더를 요구하고, API 버전을 지정하려면X-GitHub-Api-Version헤더를 사용해요. 모든 API 요청에는 유효한User-Agent헤더가 필수예요. - 인증(Authentication): 토큰을
Authorization헤더에 담아 인증해요. - 파라미터(Parameters): 경로 파라미터, 본문 파라미터, 쿼리 파라미터가 있어요.
curl로 인증 요청을 보내는 기본 예시는 다음과 같아요.
curl --request GET \
--url "https://api.github.com/octocat" \
--header "Authorization: Bearer YOUR-TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28"
인증 (Authentication)
많은 REST API 엔드포인트는 인증을 요구하거나, 인증된 경우 추가 정보를 반환해요. 또한 인증을 하면 시간당 더 많은 요청을 보낼 수 있어요. 인증 토큰을 얻는 방법은 크게 세 가지예요.
- personal access token 생성 — 개인적인 용도로 사용할 때 권장해요. 가능하면 fine-grained personal access token을 사용하는 게 좋아요.
- GitHub App으로 토큰 생성 — 조직을 위해 또는 다른 사용자를 대신해 API를 사용할 때 권장해요.
- GitHub Actions 워크플로의 내장
GITHUB_TOKEN사용 — 워크플로에서 인증할 때 권장해요.
토큰을 만든 뒤에는 요청의 Authorization 헤더에 담아 보내면 돼요.
curl --request GET \
--url "https://api.github.com/octocat" \
--header "Authorization: Bearer YOUR-TOKEN" \
--header "X-GitHub-Api-Version: 2026-03-10"
참고: 대부분의 경우
Authorization: Bearer또는Authorization: token으로 토큰을 전달할 수 있어요. 다만 JSON 웹 토큰(JWT)을 전달할 때는Authorization: Bearer를 사용해야 해요.
토큰 없이 또는 권한이 부족한 토큰으로 REST API 엔드포인트를 사용하려 하면 404 Not Found나 403 Forbidden 응답을 받아요. 잘못된 자격 증명으로 인증하면 처음에는 401 Unauthorized 응답이 반환되다가, 짧은 시간 안에 잘못된 자격 증명 요청이 여러 번 감지되면 해당 사용자의 모든 인증 시도를 403 Forbidden으로 일시적으로 거부해요.
Rate limit (요청 한도)
GitHub는 특정 시간 안에 보낼 수 있는 REST API 요청 수를 제한해요. 이는 남용을 막고 서비스 거부 공격을 방지하며, 모든 사용자에게 API를 계속 사용 가능하게 유지하기 위한 것이에요. 기본(primary) rate limit은 인증 방식에 따라 달라져요.
- 비인증 사용자: 시간당 60회 요청. 공개 데이터를 가져올 때만 사용할 수 있어요. 요청은 사용자나 애플리케이션이 아니라 출발 IP 주소와 연결돼요.
- 인증된 사용자: personal access token 기준 시간당 5,000회 요청. GitHub App이나 OAuth 앱이 대신 보내는 요청도 이 한도에 포함돼요. GitHub Enterprise Cloud 조직이 소유한 GitHub App/OAuth 앱이 대신 보내는 요청은 시간당 15,000회로 더 높아요.
- Git LFS 접근: 비인증 300회/분, 인증 3,000회/분의 별도 버킷으로 계산돼요.
- GitHub App 설치: 설치 접근 토큰은 시간당 5,000회(엔터프라이즈 클라우드 조직이면 15,000회) 한도를 사용하며, 저장소/사용자 수에 따라 최대 12,500회/시간까지 조정될 수 있어요.
- GitHub Actions의
GITHUB_TOKEN: 저장소당 시간당 1,000회.
이런 기본 rate limit 외에도 동시 요청(100개), 단일 엔드포인트 분당 요청, CPU 시간, 콘텐츠 생성 등에 적용되는 보조(secondary) rate limit도 있어요.
응답 헤더를 통해 현재 rate limit 상태를 확인할 수 있어요.
| 헤더 | 설명 |
|---|---|
x-ratelimit-limit |
시간당 보낼 수 있는 최대 요청 수 |
x-ratelimit-remaining |
현재 rate limit 창에서 남은 요청 수 |
x-ratelimit-used |
현재 rate limit 창에서 사용한 요청 수 |
x-ratelimit-reset |
현재 rate limit 창이 초기화되는 시각 (UTC epoch 초) |
x-ratelimit-resource |
요청이 집계된 rate limit 리소스 |
rate limit을 초과하면 403 또는 429 응답과 함께 x-ratelimit-remaining 헤더가 0으로 표시돼요. x-ratelimit-reset 헤더에 지정된 시각 이후에 재시도해야 해요. OAuth 앱은 클라이언트 ID와 시크릿으로 공개 데이터를 가져올 수도 있어요.
curl -u YOUR_CLIENT_ID:YOUR_CLIENT_SECRET -I https://api.github.com/meta
참고: 앱의 클라이언트 시크릿을 클라이언트 측 코드나 사용자 기기에서 실행되는 코드에 절대 포함하지 마세요. 클라이언트 시크릿은 앱을 승인한 사용자의 OAuth 접근 토큰을 생성하는 데 사용될 수 있으니, 항상 안전하게 보관해야 해요.
Rate limit을 높이려면 비인증 요청 대신 인증 요청을 사용하는 것이 가장 좋은 방법이에요. 인증 요청의 rate limit이 훨씬 높거든요.
주요 엔드포인트와 사용 예시
엔드포인트는 리소스에 따라 분류되어 있어요. 대표적인 카테고리는 다음과 같아요. 이슈, 풀 리퀘스트, 커밋, 저장소, 릴리스, 검색 등이 있으며, 각 엔드포인트의 HTTP 메서드, 경로, 파라미터는 REST 참조 문서에서 확인할 수 있어요.
다음은 자주 사용하는 예시들이에요.
GitHub CLI로 Octocat 조회하기
gh api --method GET /octocat \
--header 'Accept: application/vnd.github+json' \
--header "X-GitHub-Api-Version: 2022-11-28"
curl로 쿼리 파라미터 사용해서 이벤트 목록 가져오기
curl --request GET \
--url "https://api.github.com/events?per_page=2&page=1" \
--header "Accept: application/vnd.github+json" \
--header "X-GitHub-Api-Version: 2022-11-28"
curl로 이슈 생성하기 (본문 파라미터 사용)
curl \
--request POST \
--url "https://api.github.com/repos/octocat/Spoon-Knife/issues" \
--header "Accept: application/vnd.github+json" \
--header "X-GitHub-Api-Version: 2022-11-28" \
--header "Authorization: Bearer YOUR-TOKEN" \
--data '{
"title": "Created with the REST API",
"body": "This is a test issue created by the REST API"
}'
참고: fine-grained personal access token을 사용한다면
octocat/Spoon-Knife를 본인이 소유하거나, 본인이 멤버인 조직이 소유한 저장소로 바꿔야 해요. 토큰은 해당 저장소에 접근 권한이 있어야 하고, 저장소 이슈에 대한 읽기·쓰기 권한이 있어야 해요.
JavaScript (Octokit.js)로 이슈 생성하기
const octokit = new Octokit({
auth: 'YOUR-TOKEN'
});
await octokit.request("POST /repos/{owner}/{repo}/issues", {
owner: "octocat",
repo: "Spoon-Knife",
title: "Created with the REST API",
body: "This is a test issue created by the REST API",
});
응답 사용하기
요청을 보내면 API는 응답 상태 코드, 응답 헤더, 그리고 경우에 따라 응답 본문을 반환해요.
- 상태 코드와 헤더: 모든 요청은 성공 여부를 나타내는 HTTP 상태 코드를 반환해요.
X-또는x-로 시작하는 헤더는 GitHub 고유의 헤더로, 예를 들어x-ratelimit-remaining과x-ratelimit-reset은 시간당 보낼 수 있는 요청 수를 알려줘요. 상태 코드와 헤더를 보려면 요청에--include또는--i옵션을 사용하면 돼요.
curl --request GET \
--url "https://api.github.com/repos/octocat/Spoon-Knife/issues?per_page=2" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer YOUR-TOKEN" \
--include
- 응답 본문: 별도로 명시하지 않는 한 응답 본문은 JSON 형식이에요. 빈 필드는 생략하지 않고
null로 포함되며, 타임스탬프는 UTC 시간, ISO 8601 형식(YYYY-MM-DDTHH:MM:SSZ)으로 반환돼요. - Detailed vs Summary 표현: 개별 리소스를 가져올 때는 모든 속성을 포함한 "detailed" 표현을, 리소스 목록을 가져올 때는 속성 일부만 포함한 "summary" 표현을 받아요. 일부 속성은 계산 비용이 커서 summary 표현에서는 제외되거든요.
- Hypermedia: 모든 리소스에는 다른 리소스로 연결되는
*_url속성이 있을 수 있어요. 이는 명시적 URL을 제공해 API 클라이언트가 URL을 직접 만들지 않도록 하기 위한 것이며, 사용을 권장해요.