01概要
MonoUni プラットフォームは、「場所(サイト)」に紐づく機器に対して、Web API から アクション(動詞)を送ると、現地のインター(中継機)経由で機器が制御される仕組みです。 本リファレンスはサードパーティアプリ(OAuth クライアント)が公開 API を利用するための契約をまとめます。
ベース URL と形式
- すべてのエンドポイントは本コンソールと同一オリジン(
https://monouni-actions.web.app)配下の/api/...・/oauth/...です。 - リクエスト/レスポンスボディは JSON(
Content-Type: application/json)。 - エラーは HTTP ステータス+
{ "error": "<code>" }形式(例forbidden/invalid_request/payload_too_large)。
全体フロー
開発者アカウント(developer ロール)
│ 開発者ページ 画面で OAuth クライアントを作成
▼
OAuth クライアント(server / confidential / public)
│ トークンを取得(/oauth/token)
▼
アクセストークン(Authorization: Bearer <accessToken>)
│ ① 場所と機器を特定(GET /api/sites, /api/.../devices)
│ ② アクションを送信(POST /api/sites/{siteId}/devices/{deviceId}/{action})
▼
プラットフォームが現地インターへ配信・実行
│ ③ ステータス監視(GET /api/actions/{actionId})/ Webhook callback
▼
完了(result)
認証方式
| 方式 | ヘッダー | 用途 |
|---|---|---|
| OAuth Access Token | Authorization: Bearer <accessToken> | サードパーティクライアント(本リファレンスの対象) |
| なし(公開エンドポイント) | — | アクション状態の参照(actionId 自体が capability token・→ ステータス監視) |
02OAuth 認証
本 API の認可は OAuth 2.0(RFC 6749)+
PKCE(RFC 7636・S256 必須)で、
トークンは Bearer(RFC 6750)で提示します。
ユーザー識別が要る場合は OpenID Connect(openid スコープ+ /oauth/userinfo)に対応します。
クライアントは「開発者ページ」画面から作成します。アクセス範囲とアクセス元の回答に応じて、 以下の 3 種別と適切なグラントが自動的に決まります。
クライアント種別
| 種別 | グラント | 用途 |
|---|---|---|
server | client_credentials | ユーザー操作を介さないサーバー連携。作成者(ownerUid)の権限を継承。refresh なし |
confidential | authorization_code + PKCE | 秘密鍵を安全に保持できるサーバーサイドアプリ(他ユーザーの同意を得る) |
public | authorization_code + PKCE | SPA / モバイル等。秘密鍵を持たず PKCE が所持証明 |
エンドポイント
Authorization Code フローの開始。response_type=code ・ client_id ・ redirect_uri ・ scope ・ state ・ code_challenge(S256 必須・plain は拒否)。同意画面を経て redirect_uri へ code を返します。
redirect_uri はクライアント登録時に指定した redirectUris のいずれかと完全一致する必要があります(前方一致・ワイルドカード不可)。confidential / public 種別では登録必須。state + PKCE と併せて保護するため、redirect 先の IP 制限は行いません。
トークン発行。grant_type に authorization_code / refresh_token / client_credentials。
# client_credentials の例
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=...&client_secret=...&scope=sites:read devices:print
→ { "access_token": "...", "token_type": "Bearer", "expires_in": 3600 }
発行後は全 /api/... 呼び出しに Authorization: Bearer <access_token> を付けます。server(client_credentials)は refresh_token を返さないため、失効時(1 時間)は再取得します。confidential / public は refresh_token でローテーション更新できます。
OIDC UserInfo(openid / profile / email スコープ)。
スコープ
スコープは「参照/設定」は サイト軸(sites:*)、「操作の実行」は
動詞ごとの機器軸(devices:{動詞})です。devices:all は全動詞を含む包括スコープ。
スコープは権限を縮小するのみで、サイトメンバーシップと AND で評価されます(→ 権限)。
| scope | 意味 |
|---|---|
openid / profile / email | OIDC(UserInfo の sub / name / email 等) |
sites:read | サイト配下リソース(場所・機器・インター)の参照。非破壊の status 実行も可 |
sites:write | 機器の名前・監視設定(monitored)等の変更 |
sites:owner | 削除など所有者操作 |
devices:all | 全機器操作(動詞スコープの包括・上級者向け) |
devices:print / devices:open | 印刷(プリンタ) / ドロワー開放 |
devices:status / devices:scrutiny / devices:total | 状態取得 / 在高精査(両替機) / 取引合計(決済) |
devices:identify | 機器の識別(プロビジョニング) |
devices:deposit / devices:dispense | 💰 入金 / 出金(両替機・不可逆) |
devices:pay / devices:refund | 💰 決済 / 返金(決済端末・不可逆) |
後方互換: 旧 sites:execute は devices:all として扱われます(全動詞を許可)。
トークンのライフサイクル
| トークン | 有効期間 | 備考 |
|---|---|---|
| 認可コード | 5 分 | 1 回限り(使用済みフラグ) |
| アクセストークン | 1 時間 | expires_in: 3600 |
| リフレッシュトークン | 30 日 | 使用ごとにローテーション(旧削除・新規発行) |
03場所と機器の特定
アクション送信には サイト ID(場所)と デバイス ID(機器)が必要です。
いずれの参照も sites:read スコープ+対象サイトの read / owner 権限が要ります。
siteId / deviceId はサーバーが発行する不透明な文字列で、
サイト名やアプリ名ではありません(例 /api/sites/Xk3p9QfT2mVrDs8bLqAe/devices/9dLm2aBcQ7yPnW4kZuXs/print)。取得方法は 2 つ:
① API — GET /api/devices 一発で全サイト横断に並びます。各デバイスの id(=パスの deviceId)と、そのデバイスが属するサイトの siteIds(配列。パスにはこのどれか 1 つを siteId として使う)が入っています(サイト単位に引くなら GET /api/sites → GET /api/sites/{siteId}/devices)。
② 画面 — 開発者ページの「API を試してみる」で場所・デバイスを選ぶと実 ID 入りのリクエストが表示され、場所の画面でも機器の操作モーダルから実 ID 入りの cURL をコピーできます。
vendor × serialNumber で一意)。
アクションはデバイスに対して送り、どの物理経路で届けるかはプラットフォームが解決します(クライアントは経路を指定しません)。
サイト(場所)
自分が read / owner を持つサイトの一覧 / 詳細。
デバイス(機器)
各デバイスは vendor / serialNumber / modelName / name を持ちます。deviceId をアクション送信に使います。API はすべて デバイス単位で、物理的な接続先(アドレスやポート)は公開しません。
GET /api/devices(横断)を使えば id / siteIds を手入力せずに送信対象を列挙できます(sites:read スコープで、メンバーのサイトに紐づく全デバイスを返す)。GET /api/devices/{deviceId}(詳細)は同じデバイス 1 件を返します。
04制御の実行
デバイスにアクションを送ります。動詞ごとのスコープ devices:{action}(または包括 devices:all)
+対象サイトの execute / owner 権限が必要です。例: print なら devices:print、
deposit なら devices:deposit。status のみ sites:read でも実行できます。
機器が対応しない動詞(例: プリンタに deposit)はスコープを持っていても 422 になります。
共通エンベロープ
ボディは アクション固有パラメータに加えて、以下の共通フィールドを取れます。
推奨モード(アクション別)
mode はどの動詞でも指定できますが、動詞の性質(完了までの時間・途中経過の有無)に応じて以下を推奨します。
アクション別ペイロード仕様
以下は js/api-spec.js(仕様の単一の正) から描画しています。開発者ページの 「API を試してみる」モーダルに出る仕様パネルも同じ定義を描画するため、両者は常に一致します。
05ステータス監視
レスポンスモード
| mode | 送信時の返り | 用途 |
|---|---|---|
sync | 終端まで最大 timeout 秒待ち { actionId, status, result? } | 即時に結果が欲しい |
async | 即 { actionId, status: "pending" } | 後でポーリング / callback |
session | 即 { actionId, status: "pending" } | 継続的な event ストリーム |
状態参照(認証不要・公開)
→ { actionId, action, mode, status, result?, sentAt, completedAt? }
actionId は推測不能な capability token。status は
pending → executing → parsing → completed、または
failed / expired / offline / cancelled。
session モードの event を時系列取得(リングバッファ上限 100。超過時 truncated: true)。
非終端(pending / executing / parsing)のアクションを明示終了します。
Webhook callback
callback を指定すると、終端遷移(async/session)と event ごと(session)に POST されます。
送信先 IP はクライアントごとの IP/CIDR 許可リスト(既定 deny-all)に一致する場合のみ。
「開発者ページ → 編集」で許可リストを設定してください(https 必須・private/reserved IP は拒否)。
機器の死活・状態
デバイスの liveness(online/offline・到達性)と status(Ready/Error/Offline)で機器側の状態を把握できます(→ 場所と機器の特定)。
オフライン機器への送信
送信はキューされません(ストア&フォワード再送なし)。オフラインは 2 段階で扱われます。
| 状況 | 挙動 |
|---|---|
| 生存中の経路が 1 本も無い(機器を観測している中継機が居ない) | 送信時に即 422 no_route(アクションは作られない) |
| 経路はあるが、送信時に末端機器が応答しない | アクションは作られ、終端状態 offline で確定(再送・キューはしない)。sync は timeout 待機後に、async/session はポーリング / callback で受け取る |
復旧後に実行したい場合は、機器の liveness が online に戻ってから再送してください。
06権限
アクセス可否は OAuth スコープ × サイトメンバーシップ権限を AND で評価します。 トークンに適切なスコープがあっても、対象サイトに対する権限がなければ拒否されます(逆も同様)。
サイトメンバーシップ権限
| 権限 | できること | 必要スコープ |
|---|---|---|
read | リソースの一覧・詳細取得・ステータス確認 | sites:read |
write | 機器の名前・監視設定変更など | sites:write |
execute | デバイスへのアクション送信 | devices:{action} / devices:all |
owner | 上記すべて+サイト管理(名称変更・削除・メンバー管理) | 該当操作のスコープ |
クライアント種別と権限の出所
- server(client_credentials): 作成者(developer 本人)の
site_membershipsを継承します。自分が権限を持つサイトにのみ作用。 - confidential / public(authorization_code): 認可したエンドユーザーの権限で動作します。ユーザーが
executeを持つサイトにのみ送信可。