DOJ logoDOJ
問題
最近追加された問題保存した問題Workbooks
カテゴリDLCコンテストグループチーム掲示板
ランキング
正解数ランキングストリークランキングDOJ Powerランキング
提出状況
問題募集ログイン新規登録
DOJ logoDOJ

OI形式のサブタスク採点、Eloレーティング、Discord認証を備えたオンラインジャッジです。

問題
問題一覧カテゴリ
コミュニティ
コンテストランキング掲示板お知らせ外部のコンテストを開催するガイド
アカウント
ログイン新規登録ジャッジ状態
ポリシー
利用規約DLCの利用規則プライバシーAPI 文書言語ランタイムコンテストの順位報酬レーティングとパフォーマンス
© 2026 DOJ
All rights reserved

ポリシー

  • 利用規約
  • DLCの利用規則
  • プライバシー
  • API 文書
  • 言語ランタイム
  • コンテストの順位報酬
  • レーティングとパフォーマンス

DOJPUBLICAPI · V1

API 文書

DOJの公開ユーザー・問題・コンテスト・レーティングデータをJSONで取得できます。問題文と非公開の運用データは公開されません。

ベースURLhttps://doj.kr/api/v1
クイックスタート共通規則エンドポイントユーザー問題コンテストページ分割エラー

クイックスタート

現在のv1読み取りAPIに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
}));

共通規則

応答形式
UTF-8JSON
CORS
Access-Control-Allow-Origin: *
日時
UTCのISO 8601形式の文字列
リクエスト回数制限
IPアドレスごとに1分あたり約120リクエスト

レスポンスヘッダーの 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}/virtual-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エンドポイントで、ハンドルの大文字と小文字を区別します。検索語とパス内のハンドルは、保存されたハンドルと大文字・小文字を一致させてください。

GET/api/v1/usersユーザーを検索
名前形式デフォルト説明
qstring""ハンドルの部分一致(大文字・小文字を区別)
limit1..100201ページあたりの結果数
cursorstring-前のレスポンスの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
}
GET/api/v1/users/{handle}公開ユーザープロフィール

検索結果の項目に自己紹介、アカウント作成日時、フォロワー数とフォロー数を追加します。存在しないアカウントや非公開のアカウントは404を返します。

GET/api/v1/users/{handle}/contest-participationsコンテスト参加

終了済みの公開・招待制コンテストを開催日時の降順で返します。開催中および非公開のコンテストは含みません。limitとcursorに対応しています。

GET/api/v1/users/{handle}/virtual-participationsカテゴリーバーチャル参加履歴

公開カテゴリーで終了したバーチャル参加履歴を返します。チーム記録は実際のメンバーを基準に検索し、問題別スコアと提出は含みません。

名前形式デフォルト説明
limit1..2001001ページあたりの履歴データ数
cursorstring-前のレスポンスのnextCursor
{
  "user": { "handle": "dadas08" },
  "participations": [{
    "category": {
      "path": "algorithm/graphs",
      "contents": [
        { "locale": "en", "name": "Graphs" },
        { "locale": "ko", "name": "그래프" }
      ]
    },
    "mode": "TEAM",
    "team": { "handle": "graph-team" },
    "startedAt": "2026-09-12T09:00:00.000Z",
    "endedAt": "2026-09-12T11:00:00.000Z",
    "totalScore": 420,
    "penaltySeconds": 3510
  }],
  "nextCursor": null
}
GET/api/v1/users/{handle}/rating-historyレーティンググラフデータ

古いデータから順に返します。横軸にはoccurredAt、縦軸にはnewRatingを使用してください。非公開コンテストによる変動も数値の連続性を保ちますが、contestはnullになります。

名前形式デフォルト説明
limit1..2001001ページあたりの履歴データ数
cursorstring-前のレスポンスの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
}

問題

GET/api/v1/problems公開問題を検索
名前形式デフォルト説明
qstring""問題一覧と同じ検索構文: 表示ID、slug、タイトル、@handle、#tag、範囲、論理式
difficultyMininteger-最低難度値
difficultyMaxinteger-最大難度値
tagsCSV""すべて一致する必要があるタグ(最大10個)
sortenumdisplay_id_asc下記の並べ替え値のいずれか
limit1..100201ページあたりの結果数
cursorstring-前のレスポンスの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
}
GET/api/v1/problems/{displayId}公開問題のメタデータ

1つの問題について同じメタデータを返します。問題文、入出力の説明、制約、サンプル、解説、採点データは含みません。

コンテスト

GET/api/v1/contestsコンテストを検索
名前形式デフォルト説明
qstring""slugまたはタイトルで検索
statusenumallすべて・開催予定・開催中・終了済み
limit1..100201ページあたりの結果数
cursorstring-前のレスポンスのnextCursor
GET/api/v1/contests/{slug}コンテストのメタデータ

開催日時、個別開始型の設定、レーティング対象かどうか、問題数、説明、ルールを返します。非公開のコンテストは404を返します。

ページ分割

nextCursor が null でない場合は、解釈・変更せず次のリクエストの cursor に渡してください。フィルターや並び順を変更したら再利用しないでください。

GET /api/v1/problems?limit=20&cursor=eyJvZmZzZXQiOjIwfQ

エラーとキャッシング

HTTPエラー意味
400invalid_requestクエリの形式または範囲が不正
400invalid_cursorカーソルが不正
404not_foundリソースが存在しないか非公開
429rate_limit_exceededリクエスト回数制限を超過
502/503api_unavailableバックエンドの一時的な障害
{ "error": "not_found" }

Cache-Controlヘッダーに従い、同じデータを繰り返し取得することは避けてください。互換性を失う変更は、新しいバージョンのパスで提供します。

DOJ全般のガイドはこちら: DOJ ガイド。