Contents
1. API エンドポイントの種類と選び方
はてなブックマーク API には、大きく分けて 認証必須 REST エンドポイント と 認証不要 JSONLite エンドポイント の 2 種類が用意されています。
どちらを採用すべきかは、取得したいデータの詳細度とリアルタイム性に依存します。
1.1 認証必須 REST エンドポイント
OAuth 2.0 による認可が前提で、ブックマーク本体だけでなく コメント・タグ・ユーザー情報 といったリッチなメタデータを取得できます。
公式ドキュメント: https://developer.hatena.ne.jp/ja/documents/bookmark/apis/rest/
ポイント:フル機能が必要なアプリケーション(例:自社サービスへのブックマーク統合、ユーザー別レポート作成)では必ずこのエンドポイントを利用します。
1.2 認証不要 JSONLite エンドポイント
シンプルな JSON を返すだけの軽量 API です。認可が不要なので アクセストークン取得コストがかからない のが特徴です。主に以下の用途で活用されます。
- URL 正規化後のブックマーク総数取得
- 公開エントリのタイトル・URL 抽出
公式ドキュメント: https://developer.hatena.ne.jp/ja/documents/bookmark/apis/jsonlite/
ポイント:読み取り専用で高速応答が求められるシナリオ(例:ページビュー計測、外部サイトのサマリー表示)に適しています。
2. OAuth 2.0 認可フローの実装手順
はてなブックマークリストを取得するには、まず Hatena Developer Center にアプリケーション登録し、OAuth 2.0 の「認可コードフロー」を組み立てます。以下では「クライアント登録」から「アクセストークン取得/リフレッシュ」までを具体的に示します。
2.1 クライアント(アプリ)登録
- Hatena Developer Center にログインし、左メニューの「アプリケーション管理」 → 「新規作成」をクリック。
- 必要項目(アプリ名・説明・利用目的)を入力し、リダイレクト URI(例:
https://yourdomain.com/oauth/callback) を設定します。 - 作成完了後に表示される Client ID と Client Secret を安全な場所(環境変数やシークレットマネージャ)に保存してください。
公式手順は「認可設定」セクションに詳述されています:https://developer.hatena.ne.jp/ja/documents/bookmark/apis/rest/#auth
2.2 認可コード取得
ユーザーを以下の URL にリダイレクトさせます(GET)。scope は bookmark.read を最低限指定すればブックマーク情報が取得可能です。
|
1 2 3 4 5 6 |
https://www.hatena.com/oauth/authorize? client_id=YOUR_CLIENT_ID& redirect_uri=https%3A%2F%2Fyourdomain.com%2Foauth%2Fcallback& response_type=code& scope=bookmark.read |
ユーザーが許可すると、code パラメータ付きでリダイレクト URI が呼び出されます。サーバ側はこの code を受け取り、次のステップへ進みます。
2.3 アクセストークン取得
認可コードを使って POST リクエストを送ります。公式エンドポイントは https://www.hatena.com/oauth/token(application/x-www-form-urlencoded)です。
|
1 2 3 4 5 6 7 8 9 |
POST https://www.hatena.com/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=RECEIVED_CODE& redirect_uri=https%3A%2F%2Fyourdomain.com%2Foauth%2Fcallback& client_id=YOUR_CLIENT_ID& client_secret=YOUR_CLIENT_SECRET |
成功時のレスポンス例:
|
1 2 3 4 5 6 7 |
{ "access_token": "eyJ0eXAiOiJKV1QiLCJh...", "token_type": "Bearer", "expires_in": 3600, "refresh_token":"8f6c9a..." } |
2.4 トークンのリフレッシュ
アクセストークンは 1 時間(expires_in = 3600)で期限切れになるため、以下のパラメータで再取得します。
|
1 2 3 4 5 6 7 8 |
POST https://www.hatena.com/oauth/token Content-Type: application/x-www-form-urlencoded grant_type=refresh_token& refresh_token=YOUR_REFRESH_TOKEN& client_id=YOUR_CLIENT_ID& client_secret=YOUR_CLIENT_SECRET |
注意:
invalid_grantエラーはリダイレクト URI が登録と不一致、またはリフレッシュトークンが破棄された場合に発生します。
3. 主な REST エンドポイントとサンプルコード
以下の表は 認証必須 の代表的エンドポイントです。ベース URL は公式で公開されている https://bookmark.hatenaapis.com/v1/ です。
| エンドポイント | 主なクエリパラメータ | 用途 |
|---|---|---|
/bookmarks |
url, count, offset |
指定 URL のブックマーク一覧(コメント・ユーザー情報含む) |
/entries |
url, since, until |
エントリのメタデータ(タイトル・タグ・全コメント) |
/users/me |
(なし) | 認証中ユーザーのプロフィールとトークン有効期限確認 |
3.1 /bookmarks の取得例
リクエスト
|
1 2 3 |
GET https://bookmark.hatenaapis.com/v1/bookmarks?url=https%3A%2F%2Fexample.com&count=10 Authorization: Bearer YOUR_ACCESS_TOKEN |
レスポンス(抜粋)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "bookmarks": [ { "entry_url": "https://example.com", "title": "Example Site", "user": "alice", "comment": "便利なツールです。", "timestamp": "2026-07-04T12:34:56Z" } /* ... */ ] } |
3.2 /entries の取得例
|
1 2 3 |
GET https://bookmark.hatenaapis.com/v1/entries?url=https%3A%2F%2Fexample.com&since=2026-07-01 Authorization: Bearer YOUR_ACCESS_TOKEN |
主なフィールド
| フィールド | 内容 |
|---|---|
title |
エントリのタイトル |
tags |
登録されているタグ配列 |
comments |
ユーザーコメントオブジェクト(user, comment, timestamp) |
3.3 /users/me の取得例
|
1 2 3 |
GET https://bookmark.hatenaapis.com/v1/users/me Authorization: Bearer YOUR_ACCESS_TOKEN |
レスポンス抜粋
|
1 2 3 4 5 6 7 8 |
{ "user": { "name": "alice", "id": "alice123", "profile_image_url":"https://cdn.hatena.ne.jp/profile/alice.png" } } |
ポイント:全てのリクエストで
urlパラメータは必ず URL エンコードし、ヘッダーにAuthorization: Bearer <token>を付与してください。
4. ブックマークデータの取得・加工例(Python/PHP)
4.1 Python(標準 json と requests)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import requests def fetch_bookmarks(access_token: str, target_url: str, count: int = 20): api = "https://bookmark.hatenaapis.com/v1/bookmarks" params = {"url": target_url, "count": count} headers = {"Authorization": f"Bearer {access_token}"} resp = requests.get(api, params=params, headers=headers) resp.raise_for_status() data = resp.json() # 必要情報だけ抽出 return [ { "title": bm["title"], "url": bm["entry_url"], "user": bm["user"], "comment": bm.get("comment", "") } for bm in data.get("bookmarks", []) ] |
4.2 PHP(Laravel + Guzzle)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
use GuzzleHttp\Client; function fetchBookmarks(string $accessToken, string $targetUrl, int $count = 20): array { $client = new Client(['base_uri' => 'https://bookmark.hatenaapis.com']); $response = $client->get('/v1/bookmarks', [ 'query' => ['url' => $targetUrl, 'count' => $count], 'headers' => ['Authorization' => "Bearer {$accessToken}"] ]); $data = json_decode($response->getBody(), true); return collect($data['bookmarks'] ?? []) ->map(fn ($bm) => [ 'title' => $bm['title'], 'url' => $bm['entry_url'], 'user' => $bm['user'], 'comment' => $bm['comment'] ?? '', ])->toArray(); } |
どちらの例も 取得した JSON → 必要項目だけ抽出 → テンプレートエンジンで表示 の流れを示しています。実装時は try / catch(Python)や try { … } catch (RequestException $e) { … }(PHP)で例外処理を入れると安全です。
4.3 コメント表示用ブログパーツの埋め込み
公式が提供する「はてなブックマーク コメント表示ブログパーツ」は次のコードで利用できます。
※公式ページ: https://developer.hatena.ne.jp/ja/documents/bookmark/#comment-widget
|
1 2 3 4 5 6 7 8 |
<script src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async defer></script> <a href="https://b.hatena.ne.jp/entry/example.com/" class="hatena-bookmark-comment" data-hatena-bookmark-layout="standard"> コメントを見る </a> |
URL 正規化のベストプラクティス
- スキームは https に統一(http と https は別エントリになる)。
- トラッキングパラメータは除去(例:
?utm_…)。 - 末尾スラッシュは一貫性を保つ(公式は「末尾スラッシュあり」)。
正規化した URL を API に渡すと、期待通りのエントリが取得できます。
5. レートリミット・エラーハンドリング・デプロイチェック
5.1 レートリミット概要
- 上限:認証済みアプリは 1 分間に 60 リクエスト(公式ドキュメント2026‑04時点)。
- 超過時のステータス:
429 Too Many Requestsが返り、Retry-Afterヘッダーで待機秒数が示されます。
5.2 推奨リトライ戦略(指数バックオフ)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import time, random def request_with_retry(session, url, headers): wait = 1 while True: resp = session.get(url, headers=headers) if resp.status_code != 429: return resp retry_after = int(resp.headers.get("Retry-After", wait)) time.sleep(retry_after + random.uniform(0, 0.5)) wait = min(wait * 2, 30) # 最大待機は30秒 |
5.3 デプロイ後の動作確認チェックリスト
| 項目 | 確認手順 |
|---|---|
| OAuth 認証成功 | /login → 許可画面 → コールバックでアクセストークン取得できるか |
| ブックマーク取得 | /v1/bookmarks が 200 を返し、期待の JSON フィールドが存在するか |
| コメントウィジェット表示 | 埋め込み <a class="hatena-bookmark-comment"> が正しくレンダリングされるか |
| レートリミット遵守 | 1 分間に 60 リクエスト以下で 429 が出ないことを負荷テストで検証 |
| エラーログの有無 | サーバログに OAuthException・JSONDecodeError 等が記録されていないか |
デバッグヒント
- リダイレクト URI の不一致 →
invalid_grantエラー。設定とコードを完全一致させる。 - アクセストークン期限切れ → 1 時間ごとにリフレッシュロジックを走らせる。
- URL 正規化ミス → API が「エントリなし」(404) を返すケースが頻発するので、正規化関数のテストを書いておく。
6. まとめ
はてなブックマーク API は 認証必須 REST エンドポイント と 認証不要 JSONLite エンドポイント の二本柱で構成され、用途に応じた選択が可能です。OAuth 2.0 の認可コードフローを正しく実装すれば、公式が保証する 1 分 60 リクエスト のレートリミット内で安全にデータ取得できます。
本稿で紹介した Python / PHP のサンプルコード と デプロイチェックリスト を活用すれば、開発から本番運用までスムーズに移行できるはずです。ぜひ自社サービスや個人ブログに組み込み、読者へリアルタイムなブックマーク情報とコメント表示を提供してください。
本記事の内容は 2026 年 7 月時点の公式ドキュメント(Hatena Developer Center)に基づいています。API の仕様変更が行われた場合は、必ず最新の公式ページをご確認ください。