コンテンツにスキップ

認証 (OAuth 2.0 + DCR)

SendWOW External API は OAuth 2.0 Authorization Code Flow + PKCE + Dynamic Client Registration (RFC 7591) で保護されています。本ページはフローの各ステップとセキュリティ仕様を解説します。

最短手順は クイックスタート を参照してください。

種別URL
DCR (クライアント登録)POST https://api.sendwow.jp/api/v1/oauth/register/
AuthorizeGET https://api.sendwow.jp/api/v1/oauth/authorize/
TokenPOST https://api.sendwow.jp/api/v1/oauth/token/
RevokePOST https://api.sendwow.jp/api/v1/oauth/revoke/
Metadata (RFC 8414)GET https://api.sendwow.jp/api/v1/oauth/.well-known/oauth-authorization-server

メタデータ endpoint は trailing slash なし であることに注意してください (RFC 8414 標準)。

Terminal window
curl -X POST https://api.sendwow.jp/api/v1/oauth/register/ \
-H 'Content-Type: application/json' \
-d '{
"redirect_uris": ["https://your-app.example.com/oauth/callback"],
"token_endpoint_auth_method": "client_secret_post",
"scope": "read teams:read orders:read orders:write",
"client_name": "Acme Integration"
}'
  • redirect_uris (必須, 配列): 完全一致で照合されます。
    • https:// + ホスト名必須。例外はループバック http://127.0.0.1/... と、MCP クライアント向けの private-use scheme (cursor:// / vscode:// / vscode-insiders:// / windsurf:// / claude://)
    • fragment (#...) 含み不可、空白・制御文字含み不可
  • scope (任意): 空白区切りで scope 一覧 の値を指定します。省略時は 参照系 scope 一式 (read と各 *:read) が付与されます。write 系 (orders:write 等) は省略時に含まれないので、更新操作を行う場合は明示してください
    • 未知の scope (openid 等) は無視されます。サポート対象が 1 つも含まれない場合は 400
    • write 系 scope は対応する read scope を自動内包します (例: orders:writeread / orders:read)
  • token_endpoint_auth_method (任意, デフォルト client_secret_post):
    • client_secret_post / client_secret_basic — confidential client (client_secret 発行)
    • none — public client (PKCE のみで認証、SPA / モバイル向け)
  • client_name (任意): consent 画面に表示されます。< / > / 改行 / 制御文字は拒否
{
"client_id": "uuid-...",
"client_secret": "...",
"redirect_uris": ["https://your-app.example.com/oauth/callback"],
"scope": "read teams:read orders:read orders:write",
"client_name": "Acme Integration",
"client_id_issued_at": 1716345600
}
  • client_id / client_secret永続保存してください。再発行できません。
  • レート制限: 同一 IP から 20 回 / 時 (匿名)。大量同時登録は事前ご相談ください。
import base64, hashlib, secrets
verifier = secrets.token_urlsafe(64)
challenge = base64.urlsafe_b64encode(
hashlib.sha256(verifier.encode("utf-8")).digest()
).decode("ascii").rstrip("=")

ユーザーをブラウザで以下に誘導します:

https://api.sendwow.jp/api/v1/oauth/authorize/
?client_id=<client_id>
&redirect_uri=https://your-app.example.com/oauth/callback
&response_type=code
&code_challenge=<challenge>
&code_challenge_method=S256
&scope=read teams:read orders:read orders:write
&state=<csrf-state>
  • code_challenge_method=S256 固定 (plain は不可)
  • scope は DCR で登録した scope の範囲内で指定します (登録外の scope を要求すると invalid_scope)。省略時は登録した scope 全てが対象になります
  • state は CSRF 防止用のランダム文字列。コールバック時に検証してください
  1. SendWOW のログイン画面 (メール / パスワード) でログイン
  2. consent 画面で許可
  3. redirect_uri?code=<code>&state=<state> に戻る
Terminal window
curl -X POST https://api.sendwow.jp/api/v1/oauth/token/ \
-d grant_type=authorization_code \
-d client_id=<client_id> \
-d client_secret=<client_secret> \
-d code=<authorization_code> \
-d redirect_uri=https://your-app.example.com/oauth/callback \
-d code_verifier=<verifier>
{
"access_token": "...",
"refresh_token": "...",
"token_type": "Bearer",
"expires_in": 36000,
"scope": "read teams:read orders:read orders:write"
}
トークンTTL
access_token10 時間
refresh_token30 日 (token_family の最古 RT 起点で hard cap)
  • refresh のたびに 新しい refresh_token が発行されます (rotation)
  • ただし TTL は token_family の最古 RT の発行時刻から起算されます (個別 RT が新しくなっても reset されません)
  • rotation 後の旧 RT を再利用すると token_family 全体が即時 revoke されます (盗難検知)
    • 攻撃者が窃取した RT を使って refresh しようとした時点で正規ユーザーの現行 RT も含めて失効
    • 正当なクライアントのネットワーク瞬断後 retry でも family revoke が起きうるため、リトライは慎重に
Terminal window
curl -X POST https://api.sendwow.jp/api/v1/oauth/token/ \
-d grant_type=refresh_token \
-d refresh_token=<refresh_token> \
-d client_id=<client_id> \
-d client_secret=<client_secret>
Terminal window
curl -X POST https://api.sendwow.jp/api/v1/oauth/revoke/ \
-d token=<access_token_or_refresh_token> \
-d client_id=<client_id> \
-d client_secret=<client_secret>

scope は リソース × 操作 で分かれています。read は OAuth 接続用の基本 scope で、実データの参照には各リソースの *:read が、更新には *:write が必要です。リスクの異なる操作を 1 つの scope に束ねないため、汎用の write scope はありません。

操作エンドポイント必要 scope
whoamiGET /api/v1/external/users/users:read (MCP クライアント専用)
チーム一覧GET /api/v1/external/teams/teams:read
オーダー参照GET /api/v1/external/orders/*orders:read
オーダー作成POST /api/v1/external/orders/orders:write
コメント参照GET /api/v1/external/orders/{id}/comments/comments:read
コメント追加POST /api/v1/external/orders/{id}/comments/comments:write
コンタクト参照GET /api/v1/external/contacts/*contacts:read
タッチ参照GET /api/v1/external/touches/*touches:read
タッチ作成POST /api/v1/external/touches/touches:write
商品一覧GET /api/v1/external/products/products:read
キャンペーン参照GET /api/v1/external/order_campaigns/*campaigns:read
既定チーム更新PATCH /api/v1/external/users/users:write (MCP クライアント専用)

users/ の 2 操作は /api/v1/oauth/mcp/register/ で登録した MCP クライアントのトークンのみ受け付けます。/api/v1/oauth/register/ で登録した一般クライアントからは呼び出せません。

write 系 scope を要求すると、対応する read scope が自動的に付与されます (DCR / authorize / consent のどの経路でも同じ)。

要求した scope自動付与される scope
orders:writeread, orders:read
comments:writeread, comments:read
users:writeread, users:read
touches:writeread, touches:read, products:read

必要な操作の scope だけを要求してください。例えば comments:write のトークンではオーダー作成 (orders:write) はできません。必要な scope を持たないトークンでの呼び出しは 403 Forbidden になります。

/api/v1/external/orders/ / contacts/ / touches/ / products/ / order_campaigns/ 系は Current-Team: <team_uuid> ヘッダ必須です。例外:

  • GET /api/v1/external/teams/ (利用可能チーム一覧)
  • GET /api/v1/external/users/ (whoami、MCP クライアント専用)

チーム ID は teams エンドポイントで取得できます。

項目内容回避策
DCR 必須事前固定 client_id は提供していません各クライアントで起動時に DCR を 1 度実行
iPaaS (Zapier / Make.com)DCR 非対応現状は SDK / 自社実装が主用途
ログイン認証方式認可画面はメール / パスワードのみSSO 専用アカウントは同一ブラウザで SSO ログイン済みの場合のみ可。自動化用途は共通アカウントを利用
DCR throttle20/hour (匿名 IP)通常運用では十分。大量同時登録は事前ご相談
.well-known 配置issuer root は内部 (MCP) 用/api/v1/oauth/.well-known/oauth-authorization-server を明示参照