다음 화면과 최신 데이터를 준비하고 있습니다.
다음 화면과 최신 데이터를 준비하고 있습니다.
DOJ PUBLIC API · V1
DOJ의 공개 사용자, 문제, 대회, 레이팅 데이터를 읽기 전용 JSON으로 제공합니다. 문제 지문과 비공개 운영 데이터는 포함하지 않습니다.
https://doj.kr/api/v1현재 v1 읽기 API는 별도 인증 키가 필요하지 않습니다. 브라우저와 서버에서 모두 호출할 수 있습니다.
const response = await fetch("https://doj.kr/api/v1/users/dadas08/rating-history?limit=200");
if (!response.ok) throw new Error(`DOJ API: ${response.status}`);
const { points } = await response.json();
const chartData = points.map(({ occurredAt, newRating }) => ({
x: new Date(occurredAt),
y: newRating
}));Access-Control-Allow-Origin: *남은 요청 수는 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset 응답 헤더에서 확인할 수 있습니다. 제한은 여러 서버 인스턴스에서 근사치로 적용될 수 있습니다.
비공개 문제와 대회, 대회 중인 문제 목록, 이메일, Discord 계정, 권한 정보, 제출 코드는 반환하지 않습니다. 프로필 이미지 URL은 공개 전달 경로만 반환하며 오래된 Base64 이미지는 생략될 수 있습니다.
| 메서드 | 경로 | 내용 |
|---|---|---|
| GET | /api/v1/tags | 알고리즘 태그 목록 |
| GET | /api/v1/users | 사용자 검색 |
| GET | /api/v1/users/{handle} | 사용자 공개 정보 |
| GET | /api/v1/users/{handle}/contest-participations | 종료된 대회 참가 기록 |
| GET | /api/v1/users/{handle}/rating-history | 레이팅 그래프용 변경 이력 |
| GET | /api/v1/problems | 공개 문제 검색 |
| GET | /api/v1/problems/{displayId} | 공개 문제 정보 |
| GET | /api/v1/contests | 공개 대회 검색 |
| GET | /api/v1/contests/{slug} | 대회 정보 |
사용자 핸들은 모든 사용자 API에서 대소문자를 구분합니다. 검색어와 경로의 핸들을 실제 표기와 같은 대소문자로 입력해야 합니다.
/api/v1/users사용자 검색| 이름 | 형식 | 기본값 | 설명 |
|---|---|---|---|
q | string | "" | 핸들 일부(대소문자 구분) |
limit | 1..100 | 20 | 한 페이지 결과 수 |
cursor | string | - | 이전 응답의 nextCursor |
GET /api/v1/users?q=dadas&limit=20
{
"users": [{
"handle": "dadas08",
"rating": 1542,
"contestsCount": 12,
"solvedProblemCount": 84,
"certified": true,
"avatarUrl": "/api/storage-assets/...",
"countryCode": "KR",
"organization": null
}],
"nextCursor": null
}/api/v1/users/{handle}사용자 공개 정보검색 응답 필드에 자기소개, 가입 시각, 팔로워·팔로잉 수를 더해 반환합니다. 존재하지 않거나 공개할 수 없는 계정은 404입니다.
/api/v1/users/{handle}/contest-participations대회 참가 기록종료된 공개·초대 전용 대회만 대회 시작 시각 내림차순으로 반환합니다. 진행 중인 대회와 비공개 대회는 제외합니다. limit과 cursor를 사용할 수 있습니다.
/api/v1/users/{handle}/rating-history레이팅 그래프 데이터오래된 기록부터 반환합니다. x축에는 occurredAt, y축에는 newRating을 사용하면 됩니다. 비공개 대회에서 생긴 변화는 수치 연속성을 유지하되 contest를 null로 반환합니다.
| 이름 | 형식 | 기본값 | 설명 |
|---|---|---|---|
limit | 1..200 | 100 | 한 페이지 기록 수 |
cursor | string | - | 이전 응답의 nextCursor |
{
"user": { "handle": "dadas08" },
"points": [{
"id": "...",
"occurredAt": "2026-07-21T09:00:00.000Z",
"oldRating": 1501,
"newRating": 1542,
"delta": 41,
"kind": "CONTEST",
"contest": {
"slug": "doj-contest-1",
"title": "DOJ Contest 1",
"startAt": "2026-07-21T09:00:00.000Z"
}
}],
"nextCursor": null
}/api/v1/problems공개 문제 검색| 이름 | 형식 | 기본값 | 설명 |
|---|---|---|---|
q | string | "" | 번호, slug 또는 제목 검색 |
difficultyMin | integer | - | 최소 난이도 값 |
difficultyMax | integer | - | 최대 난이도 값 |
tags | CSV | "" | 모두 포함해야 할 태그, 최대 10개 |
sort | enum | display_id_asc | 아래 정렬값 중 하나 |
limit | 1..100 | 20 | 한 페이지 결과 수 |
cursor | string | - | 이전 응답의 nextCursor |
display_id_asc display_id_desc difficulty_asc difficulty_desc solves_desc published_desc
GET /api/v1/problems?tags=dp,graphs&difficultyMin=6&sort=solves_desc
{
"problems": [{
"displayId": 95,
"slug": "95",
"titles": { "ko": "문제 제목", "en": "Problem title" },
"difficulty": 12,
"solveCount": 37,
"timeLimitMs": 2000,
"pythonTimeLimitMs": 4000,
"memoryLimitMb": 512,
"problemType": "STANDARD",
"tags": ["dp", "graphs"],
"authors": ["setter"],
"reviewers": [],
"publishedAt": "2026-08-01T00:00:00.000Z"
}],
"nextCursor": null
}/api/v1/problems/{displayId}공개 문제 정보목록과 같은 메타데이터를 한 문제에 대해 반환합니다. 지문, 입출력 설명, 제한, 예제, 에디토리얼과 채점 데이터는 포함하지 않습니다.
/api/v1/contests대회 검색| 이름 | 형식 | 기본값 | 설명 |
|---|---|---|---|
q | string | "" | slug 또는 제목 검색 |
status | enum | all | all, upcoming, running, ended |
limit | 1..100 | 20 | 한 페이지 결과 수 |
cursor | string | - | 이전 응답의 nextCursor |
/api/v1/contests/{slug}대회 정보시작·종료 시각, window 설정, rated 여부, 문제 수와 함께 설명·규칙을 반환합니다. 비공개 대회는 404로 처리합니다.
목록 응답의 nextCursor가 null이 아니면, 값을 해석하거나 수정하지 말고 다음 요청의 cursor에 그대로 전달하세요. 필터나 정렬을 바꾸면 기존 커서를 재사용하지 마세요.
GET /api/v1/problems?limit=20&cursor=eyJvZmZzZXQiOjIwfQ| HTTP | 오류 | 의미 |
|---|---|---|
| 400 | invalid_request | 쿼리 형식이나 범위가 잘못됨 |
| 400 | invalid_cursor | 사용할 수 없는 커서 |
| 404 | not_found | 없거나 공개되지 않은 리소스 |
| 429 | rate_limit_exceeded | 요청 제한 초과 |
| 502/503 | api_unavailable | 일시적인 백엔드 오류 |
{ "error": "not_found" }응답의 Cache-Control을 존중하고, 같은 데이터를 짧은 간격으로 반복 요청하지 마세요. v1에서 호환되지 않는 변경이 필요하면 새 버전 경로를 사용합니다.
일반 DOJ 이용 안내는 DOJ 안내를 참고하세요.