業務システム

Dropbox APIとは:短期トークンの取得とファイル操作・共有リンク・Webhookの実装手順

Dropbox APIとは:短期トークンの取得とファイル操作・共有リンク・Webhookの実装手順

Dropbox APIは、Dropboxに置いたファイルとフォルダ、共有リンク、チームの名前空間を、自社システムからHTTPで操作するためのAPIです。この記事では、Dropbox APIとは何かを押さえたうえで、アクセス範囲とスコープの決め方、短期アクセストークンとリフレッシュトークンの取得、一覧取得と分割アップロード、共有リンクの発行、レート制限とWebhookの扱いを、curlとPython SDKのコード例付きで順に説明します。仕様と数値は2026年11月時点のDropbox公式ドキュメントに基づきます。

まとめ:Dropbox APIで連携を作る前に決める認証・上限・共有範囲の結論

無人で動くバッチや基幹システムとの連携なら、認可コードフローにtoken_access_type=offlineを付けてリフレッシュトークンを一度だけ取得し、以後は短期トークンを自動で取り直す構成にします。開発用に画面から発行した長いトークンを本番に置く作り方は、現行の仕様では成り立ちません。

ファイル操作で覚える数字は3つです。1回のリクエストは150MiBまで、分割アップロードの追記は4MiBの倍数、アップロードセッションの寿命は7日です。チームのDropboxを扱う場合は、Dropbox-API-Path-Rootヘッダーを付けないとチームスペースが見えません。ここは要件定義の段階で確かめます。

レート制限の上限値は非公開なので、429を前提にした再試行と書き込みの一括化を先に設計します。保存先を変えるだけの連携ならiPaaSで足り、変更検知や共有リンクの自動発行を業務に組み込む場合にAPI開発の価値が出ます。

Dropbox APIでできることとエンドポイント・SDK・アプリ種別の全体像

apiとcontentの2つのホストで動くDropbox APIの構成と呼び出し方

Dropbox APIの呼び出しは、送るデータの種類でホストが分かれます。一覧取得や共有リンクの作成など、引数も応答もJSONのものはapi.dropboxapi.comです。ファイル本体を送受信するものはcontent.dropboxapi.comで、files/uploadのリファレンスのとおり、引数はJSONにしてDropbox-API-Argヘッダーに入れ、本文にはバイナリをそのまま載せます。

日本語のファイル名は要注意です。Dropbox-API-Argの中の非ASCII文字は\uXXXX形式でのエスケープが必要で、Pythonのjson.dumpsは既定でこの形式を出力します。外向き通信を許可制にしている社内ネットワークでは、2つのホストを両方許可しないとアップロードだけが失敗します。

App folderとFull Dropboxのアクセス範囲とスコープの選び方

アプリはApp Consoleで作成し、最初にアクセス範囲を選びます。公式のOAuthガイドによると、App folderはDropbox内の/Apps配下にある自分専用のフォルダだけを、Full Dropboxは利用者のDropbox全体を扱えます。

そのうえで、読み書きの操作ごとにスコープを付けます。一覧取得にはfiles.metadata.read、アップロードにはfiles.content.write、共有リンクの作成にはsharing.writeが必要です。ガイドは「必要最小限の権限だけを求める」方針を示しています。社外の取引先から書類を受け取るだけの連携ならApp folderで足ります。既存の部署フォルダを読む要件があるときだけFull Dropboxを選んでください。

利用者個人として動くアプリと、チーム全体として動くアプリも区別されます。チームのスコープで認可したトークンが結び付く先は、認可した管理者ではなくチームです。個々のメンバーとして操作するときはDropbox-API-Select-Userヘッダーでメンバーを指定します。

Python SDKは12系でPython 3.11以上、古いコード例との差に注意

公式SDKはSDKの一覧にまとまっています。Python版のdropbox-sdk-pythonはpip install dropboxで入り、対応はPython 3.11以上です。PyPIの登録情報では、2026年11月時点の最新は12.2系(12.2.4、2026年10月22日公開)でした。

リポジトリの冒頭には、APIサーバーとの互換のためv12.0.2以降を使うよう案内があります。11系以前のSDKで書かれた古い解説のコードは、そのまま動かない可能性があります。社内の古いスクリプトを引き継ぐ場合は、最初にpip show dropboxで版を確かめてください。

短期アクセストークンとリフレッシュトークンで無人バッチの認証を組む手順

expires_inで返る短期トークンの寿命とoffline指定のリフレッシュトークン

Dropboxのアクセストークンは短期で、一定時間で失効します。認可のリファレンスに載っている応答例ではexpires_inが14400秒(4時間)ですが、寿命は応答の値で判断し、固定値を埋め込まないでください。

利用者が画面を開いていない時間にも動くアプリは、認可URLにtoken_access_type=offlineを付けてリフレッシュトークンを受け取ります。OAuthガイドの推奨は、アプリの形で次のように分かれます。

アプリの形 推奨される組み合わせ
利用者の操作中だけ呼ぶサーバー側Webアプリ 認可コードフロー+短期トークンのみ
ブラウザだけで動くJavaScriptアプリ 認可コードフロー+PKCE+短期トークンのみ
夜間バッチなど無人で動くサーバー側アプリ 認可コードフロー+リフレッシュトークン
無人で同期するデスクトップ・モバイルアプリ 認可コードフロー+PKCE+リフレッシュトークン

PKCEは、アプリの秘密情報を端末に置けない場合のための仕組みです。認可コードフローそのものの流れはOAuth 2.0の仕組みと認可フローの解説を参照してください。

認可コードをcurlで一度だけ交換しリフレッシュトークンを取得する手順

社内の連携用アカウントでリフレッシュトークンを1本取るだけなら、リダイレクト先のサーバーを用意しなくても済みます。redirect_uriを付けずに認可URLを開くと、許可した後の画面に認可コードが表示されます。

# 1. ブラウザで開き、連携用アカウントで「許可」を押して表示されたコードを控える
https://www.dropbox.com/oauth2/authorize?client_id=${DBX_APP_KEY}&response_type=code&token_access_type=offline

# 2. コードをリフレッシュトークンに交換する
curl -s https://api.dropboxapi.com/oauth2/token \
  -u "${DBX_APP_KEY}:${DBX_APP_SECRET}" \
  -d grant_type=authorization_code \
  -d code="${AUTH_CODE}"

# 3. 以後はリフレッシュトークンで短期トークンを取り直す
curl -s https://api.dropboxapi.com/oauth2/token \
  -u "${DBX_APP_KEY}:${DBX_APP_SECRET}" \
  -d grant_type=refresh_token \
  -d refresh_token="${DBX_REFRESH_TOKEN}"

トークン発行の呼び出しは、アプリキーとアプリシークレットで認証します。上の例はBasic認証の形で、POSTのパラメータでclient_idとclient_secretを送る形も使えます。リフレッシュの応答に新しいリフレッシュトークンは入りません。最初に受け取った1本を秘密情報の保管庫に入れ、利用者が連携を解除するまで使い続けます。

Python SDKにリフレッシュトークンを渡して自動更新させる書き方

SDKにリフレッシュトークンとアプリキーを渡すと、短期トークンの取得と期限切れ時の取り直しをSDKが受け持ちます。

# pip install dropbox
import os

import dropbox

dbx = dropbox.Dropbox(
    oauth2_refresh_token=os.environ["DBX_REFRESH_TOKEN"],
    app_key=os.environ["DBX_APP_KEY"],
    app_secret=os.environ["DBX_APP_SECRET"],  # PKCEで認可した場合は不要
    max_retries_on_rate_limit=5,  # 既定のNoneだと429で無制限に再試行する
)

account = dbx.users_get_current_account()
print(account.email, account.root_info.root_namespace_id)

SDKのAPIリファレンスによると、max_retries_on_rate_limitの既定値Noneは「429のたびに無制限に再試行する」という意味です。夜間バッチでは上限を明示しておかないと、制限が続いた日にジョブが終わらず、翌日の処理と重なります。

ファイル操作の実装:一覧取得のcursorと150MiBを超える分割アップロード

list_folderとcontinueで全件を取る書き方とrecursiveの落とし穴

フォルダの中身はfiles/list_folderで取得します。list_folderのリファレンスのとおり、1回で返りきらないときはhas_moreが真になり、応答のcursorをfiles/list_folder/continueに渡して続きを取ります。ルートの指定は空文字列です。

res = dbx.files_list_folder("/取引先/2026", limit=500)
entries = list(res.entries)
while res.has_more:
    res = dbx.files_list_folder_continue(res.cursor)
    entries.extend(res.entries)

saved_cursor = res.cursor  # 次回はここから差分だけを取れる

recursive=Trueは手軽ですが、リファレンスには「項目数の多い構成では性能の問題やエラーにつながりうる」と書かれています。部署全体のように深いフォルダをたどるなら、再帰を切ってサブフォルダを1つずつ処理する書き方が勧められています。

150MiBまでの通常アップロードとmodeによる上書き・競合の制御

150MiB以下のファイルはfiles/uploadで1回で送れます。同じパスにファイルがあったときの動きはmodeで決まり、addは既存を上書きしない、overwriteは常に上書き、updateは指定した版(rev)が現在の版と一致したときだけ上書きします。既定はaddです。

連携の実務で使い分けるなら、システムが正となる帳票の出力はoverwrite、人も編集するファイルへの書き戻しはupdateです。updateなら、取得してから書き戻すまでの間に誰かが手で直した場合に競合として失敗し、他人の編集を黙って消す事故を防げます。addにautorename=Trueを組み合わせると、同名ファイルは「ファイル名 (1).pdf」のような別名で保存されます。

150MiB超はupload_sessionで4MiBの倍数ずつ送る分割アップロード

150MiBを超えるファイルはアップロードセッションで分割して送ります。upload_session/startのリファレンスによると、1回のリクエストは150MiBまで、最後以外の追記は4MiB(4,194,304バイト)の倍数、セッションの寿命は7日です。セッションで送れる1ファイルの上限は2の41乗から2の22乗を引いたバイト数(約2TiB)です。

import os

from dropbox.files import CommitInfo, UploadSessionCursor, WriteMode

CHUNK = 8 * 1024 * 1024  # 4MiBの倍数にする


def upload_large(dbx, local_path, dropbox_path):
    size = os.path.getsize(local_path)
    with open(local_path, "rb") as f:
        start = dbx.files_upload_session_start(f.read(CHUNK))
        cursor = UploadSessionCursor(session_id=start.session_id, offset=f.tell())
        commit = CommitInfo(path=dropbox_path, mode=WriteMode.overwrite)
        while size - f.tell() > CHUNK:
            dbx.files_upload_session_append_v2(f.read(CHUNK), cursor)
            cursor.offset = f.tell()
        return dbx.files_upload_session_finish(f.read(CHUNK), cursor, commit)

途中で通信が切れても、セッションが7日間有効なうちはoffsetの位置から続きを送れます。送信済みのバイト数をoffsetとして保存しておけば、数GBの動画や図面データを最初から送り直さずに済みます。

共有リンクと権限の実装:audience・期限・パスワードとチームスペース

共有リンク作成APIでaudienceと期限・パスワードを指定する書き方

共有リンクはsharing/create_shared_link_with_settingsで作ります。リファレンスでは、公開範囲の指定に使っていたrequested_visibilityは非推奨で、代わりにaudienceを使うよう案内されています。

import os
from datetime import datetime, timedelta, timezone

from dropbox.sharing import LinkAudience, SharedLinkSettings

settings = SharedLinkSettings(
    audience=LinkAudience.public,
    require_password=True,
    link_password=os.environ["LINK_PASSWORD"],
    expires=datetime.now(timezone.utc) + timedelta(days=14),
    allow_download=True,
)
link = dbx.sharing_create_shared_link_with_settings("/取引先/2026/見積書.pdf", settings)
print(link.url)

設定を省くと公開範囲は既定でpublicになり、リンクを知っている人なら誰でも開けます。社外へ渡す書類のリンクを自動発行するなら、期限とパスワードを明示してください。ただしリファレンスには、Basicプランの利用者は公開範囲をpublic以外にできず、期限も設定できないとあります。連携用アカウントのプランは、設計の前に確かめます。

shared_link_already_existsで止まる再実行バッチの対処

同じファイルに共有リンクが既にあると、作成APIはshared_link_already_existsのエラーを返します。前日に失敗した分をやり直すバッチでは、ここでジョブ全体が止まりがちです。

エラーには既存リンクの情報が付くことがありますが、作成時に独自の設定を指定した場合は返りません。確実に取るには、エラーを受けたらsharing_list_shared_links(path=..., direct_only=True)で既存リンクを引き直す分岐を入れます。既存リンクの公開範囲が今回の要件と違うときは、そのまま使わずに設定の変更か作り直しを判断する処理も要ります。

Dropbox-API-Path-Rootを付けないとチームスペースが見えない問題

チームで契約したDropboxをAPIで読むと、チームのフォルダが一覧に出ないことがあります。チームのファイルに関するガイドによると、チームスペース構成のアカウントでは、ヘッダーを付けない呼び出しはメンバー個人のフォルダを基点に動き、チームスペースの中身は見えません。

users/get_current_accountのroot_infoで、root_namespace_idとhome_namespace_idが異なればチームスペース構成です。チームスペース全体を基点にするには、Path Rootヘッダーのモードのうちrootモードを使います。

curl -s -X POST https://api.dropboxapi.com/2/files/list_folder \
  -H "Authorization: Bearer ${DBX_ACCESS_TOKEN}" \
  -H 'Dropbox-API-Path-Root: {".tag": "root", "root": "7"}' \
  -H "Content-Type: application/json" \
  -d '{"path": ""}'

Python SDKではdbx.with_path_root(dropbox.common.PathRoot.root(ns_id))で同じ指定ができます。ヘッダーの有無で同じ/営業部が指す場所は変わるので、設定ファイルのパスには基点も併記します。

本番運用の上限と変更検知:429・書き込み競合・Webhookの10秒制限

上限値が非公開のレート制限とRetry-Afterに従う再試行の書き方

公式のパフォーマンスガイドによると、制限に当たった呼び出しはHTTP 429とtoo_many_requestsを返し、応答には必ずRetry-Afterヘッダーが付きます。Dropboxは具体的な上限値を公開していません。

制限された要求そのものも回数に数えられるため、待たずに再試行を繰り返すと制限が長引きます。Retry-Afterの秒数だけ待つ処理は必須です。429が頻発するなら、ガイドは呼び出し方の効率が悪い兆候だとしています。待ち時間を延ばしながら再試行する書き方はリトライパターンと指数バックオフの解説、429を前提にした設計はAPIレート制限の解説にまとめています。

書き込み競合の429を減らすfinish_batchでの一括コミット

同じパフォーマンスガイドには、もう1種類の429としてtoo_many_write_operationsがあります。Dropboxは名前空間(共有フォルダやチームフォルダの単位)ごとにロックを取ってから書き込むため、同じ名前空間へ多数のスレッドが並行して書くと、ロックの取り合いで失敗します。この場合のRetry-Afterは0で、すぐに再試行してよいという意味です。

対策は、ファイルごとにコミットせずまとめて確定することです。各ファイルをアップロードセッションで送り、最後にfiles/upload_session/finish_batchを1回呼びます。1バッチは1,000件までで、1つの名前空間にそろえたほうが競合が減ります。数千件の書類の移行は、最初からこの形で組んでください。

Webhookは10秒以内に応答しlist_folder/continueで差分を取る

変更の検知には、保存したcursorで差分を取る方法、list_folder/longpollで変更まで待つ方法、Webhookの3つがあります(変更検知のガイド)。サーバー側の連携ならWebhookが基本です。

Webhookのガイドの要件は次のとおりです。登録時のGETで届くchallengeをそのまま返し、通知のPOSTはX-Dropbox-Signature(本文をアプリシークレットで署名したHMAC-SHA256)で検証し、10秒以内に応答します。

import hashlib
import hmac
import os

from flask import Flask, Response, abort, request

app = Flask(__name__)
APP_SECRET = os.environ["DBX_APP_SECRET"].encode()


@app.get("/dropbox/webhook")
def verify():
    resp = Response(request.args.get("challenge", ""), content_type="text/plain")
    resp.headers["X-Content-Type-Options"] = "nosniff"
    return resp


@app.post("/dropbox/webhook")
def notify():
    expected = hmac.new(APP_SECRET, request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(request.headers.get("X-Dropbox-Signature", ""), expected):
        abort(403)
    for account_id in request.get_json()["list_folder"]["accounts"]:
        enqueue_sync(account_id)  # 差分取得は別プロセスで行い、ここではすぐ返す
    return ""

通知に入っているのは変更のあったアカウントのIDだけで、どのファイルが変わったかは含まれません。受け取ったら、保存しておいたcursorでlist_folder/continueを呼んで差分を取ります。200以外の応答や時間切れの通知は約10分にわたって再送され、失敗が一定の基準を超えるとWebhookが無効になります。受信側の冪等性の作り方はWebhookの作り方と実装方法の記事を参照してください。

Dropbox API連携を自社開発すべき条件と見送るべき場面の判断

自社開発に進むべき条件は変更検知の同期と共有リンクの自動発行

Dropbox APIを使う開発に投資する価値があるのは、次の2つのどちらかが要件にある場合です。1つは、取引先が置いた書類をWebhookとcursorで検知し、基幹システムの案件や請求データと突き合わせて取り込みたい場合。もう1つは、受注や出荷の処理に合わせて、期限とパスワード付きの共有リンクを自動で発行し、取引先へのメールに差し込みたい場合です。

どちらも、Path Root、既存リンク、書き込み競合、10秒以内の応答といった、定型のiPaaS部品では吸収しきれない条件を含みます。

iPaaSで足りる場面とBox APIとの比較、受託開発へ相談する判断目安

「メールの添付を決まったフォルダに保存する」「新しいファイルが入ったらチャットに通知する」程度なら、APIを使う開発は過剰です。iPaaSや標準連携で数日で作れます。書類のメタデータ検索や細かい権限の自動付与が中心ならBox APIの認証とメタデータ・権限付与の実装、Microsoft 365を全社で使っているならMicrosoft Graph APIでOneDriveを扱う案も比べてください。

基幹システムとの双方向の同期、数万件規模の移行、共有リンクの自動発行のように、認証の運用、レート制限、失敗時の再実行まで含めて作る必要がある場合は、設計段階から経験のある開発会社に入ってもらうと手戻りが減ります。一創のAPI開発・システム連携サービスでは、Dropboxを含むSaaSと社内システムの連携を、要件整理から運用まで受託しています。REST連携の一般的な実装手順はAPI連携の実装方法の記事が参考になるはずです。

Dropbox APIの料金・トークン・制限について実装前によくある質問

Dropbox APIを使い始める実装者から出やすい質問に、公式ドキュメントの記載をもとに答えます。

Dropbox APIは無料で使えますか?

App ConsoleでアプリをつくればAPIを呼び出せます。2026年11月時点の公式の開発者向けドキュメントに、API呼び出しそのものの料金表は見当たりません。効いてくるのは連携に使うアカウントのプランで、容量のほか、Basicプランでは共有リンクの公開範囲と期限を指定できないという制約があります。業務の連携は有料プランのアカウントで設計してください。

以前のような期限の無いアクセストークンはもう使えませんか?

公式のOAuthガイドは、長期トークンを非推奨とし、互換のための選択肢として残すのは2021年半ばまでと記しています。現在の連携は、短期トークンとリフレッシュトークンを組み合わせる前提で作ります。古いスクリプトがApp Consoleで発行した長いトークンを直接持っている場合は、token_access_type=offlineでリフレッシュトークンを取り直し、SDKの自動更新に置き換えてください。スコープの無い旧形式のアプリは、App Consoleでスコープ付きのアプリへ変換するよう案内されています。

PKCEはどのような場合に使えばよいですか?

アプリシークレットを安全に置けない場合、つまりブラウザだけで動くJavaScriptアプリや、利用者の端末に配るアプリで使います。固定のシークレットの代わりに、認可のたびに作る値で本人のアプリかを確かめる仕組みで、公式ガイドの推奨方式はS256です。社内サーバーだけで動く連携は通常の認可コードフローで足ります。旧来のImplicitフローは互換のために残るだけで、新規のアプリにはPKCEが勧められています。

アップロードできるファイルの大きさに上限はありますか?

APIの側では、1回のリクエストが150MiBまで、アップロードセッションで送る1ファイルが約2TiBまでです。これとは別に、保存先アカウントの容量が上限になります。容量はプランで変わるため、大量の移行の前に空き容量を確かめてください。

同じフォルダを並列で一覧するとエラーになるのはなぜですか?

list_folderのリファレンスには、同じアプリが同じ利用者に対し、同じ引数のlist_folderやlist_folder/continueを同時に呼ぶと、レート制限のエラーが返ることがあると書かれています。再試行の処理を入れる場合も、前のリクエストが終わるまで次を出さないよう求められています。並列化するなら、フォルダごとに担当を分け、同じフォルダを複数のスレッドから読まない形にしてください。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.29 テックブログ ソニー生命の不正アクセス:38.5万件の対象確認と窓口、停止中の手続き
  2. 2026.10.31 テックブログ osinaの情報漏洩:約23万人の対象確認とSNS連携の解除、分析ツールへ渡すデータの絞り方
  3. 2026.10.31 テックブログ 松屋の不正アクセス:237万件の対象確認と窓口、漏れたパスワードの守り方
  4. 2026.11.01 テックブログ RAGTAGの情報漏洩:延べ約120万件の対象項目と会員の備え、侵入から検知まで11日の意味
  5. 2026.05.18 テックブログ マネーフォワードで連携できない・失敗するときの対処法|エラー別の原因と再連携のやり方

RELATED POSTS 関連記事

目次