runlot
リファレンスAPI

組織

org カテゴリの API オペレーションを 14 個カバーします。

メソッドパス説明
GET/v1/orgs
POST/v1/orgsorg を作成する
PATCH/v1/orgs/{orgSlug}org の表示名の変更(runlot org rename
DELETE/v1/orgs/{orgSlug}org の削除(runlot org delete
GET/v1/orgs/{orgSlug}/notifications最近の通知(docs/limits.md §3.4)
GET/v1/orgs/{orgSlug}/membersorg メンバー(runlot org members
POST/v1/orgs/{orgSlug}/members既存のユーザーをメンバーとして追加します(運用・自動化向け)
GET/v1/orgs/{orgSlug}/invites保留中の招待(runlot member invites
POST/v1/orgs/{orgSlug}/invitesメールで招待します(runlot member invite
DELETE/v1/orgs/{orgSlug}/invites/{inviteId}招待を取り消します(runlot member uninvite
GET/v1/invites/{token}招待をプレビューします(認証不要)
POST/v1/invites/{token}/accept招待を承諾します
PUT/v1/orgs/{orgSlug}/members/{userId}ロールを変更する(runlot org set-role
DELETE/v1/orgs/{orgSlug}/members/{userId}メンバーを削除する、または自分から脱退します(runlot member rmrunlot member leave

GET /v1/orgs

operationId listOrgs

ステータスコード説明レスポンスボディ
200所有する組織object
401

POST /v1/orgs

作成者は admin になります。個人アカウントも一人組織としてモデル化されているため(docs/mvp-scope.md)、ここに別のパスはありません。

operationId createOrg

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
201作成された組織Org
401
409

PATCH /v1/orgs/{orgSlug}

admin 以上が必要です。org.rename として監査されます。

slug はこの API サーフェスの対象外です。 slug はアドレスになる名前です(<project>.<slug>.runlot.app、証明書の SAN、クローンアドレス、顧客のリポジトリにコミットされる runlot.json 内の "org" フィールド)。そのため変更する際は、しばらくの間古い名前も生かしておく必要があります — そしてそのエイリアスこそ、0027 が導入し 0037 が削除したものです(docs/org-settings.md §2)。

operationId updateOrg

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
200更新後の orgOrgMembership
400
403
404

DELETE /v1/orgs/{orgSlug}

admin 以上が必要です。これは取り消せません。

confirm フィールドには org の slug を正確に指定する必要があります(前後の空白は取り除かれます)。この API サーフェスにはダッシュボード・CLI・スクリプトという 3 つの呼び出し元があり、それぞれが個別に実装すると、どれか一つが対応漏れになっても気づけないため、API 側でこのチェックを強制しています。

削除は org が空の場合にのみ成功します。 project・ドメイン・リポジトリ・DNS ゾーンが残っている場合、レスポンスは 409 org_not_empty となり、エンベロープの details.holdings に種類ごとの件数と一部の名前が列挙されます。この理由はスキーマレベルのものです(0044・0020・0032 の RESTRICT 制約)— 行を削除してもノードのデータはそのまま残り、何からも参照されなくなったデータは削除も課金もできなくなるためです。

他に 2 つの拒否理由があります。個人 org の場合は personal_org を返します(初回ログイン時に作成される org で、二度と再作成されません)。有効な有料サブスクリプションがある場合は active_subscription を返します(カードへの請求が続いている間に org が消えてしまうのを防ぐためです)。

org.delete の監査イベントは org より長く残りますaudit_events.org_id は ON DELETE SET NULL を使用しており、slug は target に残り続けます。

operationId deleteOrg

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
204削除済み
400
403
404
409空でない(org_not_empty)・個人 org(personal_org)・有効なサブスクリプション(active_subscriptionError

GET /v1/orgs/{orgSlug}/notifications

上限・バックアップ・リストアのイベント一覧(notifications)です。新しい順です。

sentAt が設定されている場合、メールも送信されています。設定されていない行は、まだキュー待ちであるか、受け取るメールアドレスがないかのいずれかです。後者の場合、この一覧が唯一のチャンネルです。GitHub ログインが非公開メールアドレスの場合、users.email は NULL になります(§3.3)。

viewer以上です。

operationId listNotifications

パラメーター場所必須説明
limitquery不可integer
ステータスコード説明レスポンスボディ
200通知一覧object
403
404

GET /v1/orgs/{orgSlug}/members

member 以上が必要です。

operationId listMembers

ステータスコード説明レスポンスボディ
200メンバー一覧object
403
404

POST /v1/orgs/{orgSlug}/members

これは招待ではありません。 ユーザーはすでに一度ログインしていて usersprovider+subject で識別)に存在している必要があります。存在しない場合は 404 user_not_found を返します。すでにメンバーの場合は 409 already_member を返します — ロールの変更は PUT で行います。

人を招待するための窓口は POST …/invites であり、これではありません(docs/members.md):GitHub の subject は数値の id で、管理者には知り得ない値なので、このエンドポイントはすでにそれを知っている自動化向けです。

admin 以上が必要です。member.add として監査記録されます。

operationId addMember

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
201メンバーが追加されましたMember
400
403
404組織が存在しない、またはユーザーが存在しません(user_not_found)Error
409既にメンバーです(already_member)Error

GET /v1/orgs/{orgSlug}/invites

Admin 以上。 Member 以上はメンバー一覧を閲覧できますが、招待一覧は別です — これはまだ org に属していない人のメールアドレスであり、名簿ではなく管理タスクの状態です。

承諾済みまたは取り消し済みの招待は表示されません(履歴は監査ログにあります)。期限切れの招待は表示されます — その場合の再送は管理者の仕事です。

operationId listInvites

ステータスコード説明レスポンスボディ
200招待の一覧object
403
404

POST /v1/orgs/{orgSlug}/invites

Admin 以上。メールはすぐには送信されません — cp-core の送信サイクルがキューを処理します(sentAt が空の場合はまだキュー内にあることを意味します)。

同じアドレスで再度呼び出すと再送されます:新しい招待の代わりに同じ行が更新され(新しいトークンと有効期限が設定され、ロールも変更できます)、200 が返ります。新規の招待では 201 が返ります。

すでにメンバーであるアドレスは 409 already_member を返します。保留中の招待が多すぎる場合は 409 too_many_invites を返します — これはプランの上限ではなく、送信の不正利用防止です。

招待の有効期間は 7 日間で、一度限り使用可能で、いつでも取り消せます。member.invite として監査されます。

operationId createInvite

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
200既存の招待を再送しましたInvite
201新規の招待Invite
400
403
404
409すでにメンバーです(already_member)、または保留中の招待が多すぎます(too_many_invitesError

DELETE /v1/orgs/{orgSlug}/invites/{inviteId}

Admin 以上。まだ送信されていないメールは送信されなくなります — 取り消すと送信キューもクリアされます。すでに承諾または取り消し済みの招待は 404 を返します。member.uninvite として監査されます。

operationId revokeInvite

ステータスコード説明レスポンスボディ
204取り消し済み
403
404

GET /v1/invites/{token}

認証なし。 招待リンクを受け取った人はまだログインしておらず、ログインする前にそれが何であるかを知る必要があります。トークンは 32 バイトのランダムな値なので列挙できず、これを開くことの影響は「メールを送った相手が org 名を見る」で終わります。

状態はエラーではなく値ですstate)。期限切れの招待に対して 404 を返すと、UI は「リンクが間違っている」のか「リンクが古い」のかを区別できなくなります。

不明なトークンは 404 を返します — ずっと前に取り消されたトークンと同じ応答です。

operationId getInvite

ステータスコード説明レスポンスボディ
200招待InviteView
404

POST /v1/invites/{token}/accept

ログインが必要です。ログイン中のアカウントのメールアドレスが招待先アドレスと一致しなければならないというルールはありません — GitHub のプライベートメールでサインインした人には users.email 自体が存在しない場合があり、そのルールを追加するとすべての org から締め出されてしまいます。代わりに、招待は 7 日間有効で、使い切りであり、いつでも取り消すことができ、監査記録には招待先アドレスと承諾したアカウントの両方が残ります。

すでにメンバーである場合、ロールは変更されません(alreadyMember: true)。もし招待が管理者を降格させる経路になってしまうと、その降格は last-admin チェックを通過しません。

member.accept として監査記録されます。

operationId acceptInvite

ステータスコード説明レスポンスボディ
200承諾済みobject
401
404
409すでに承諾済み(invite_used)、取り消し済み(invite_revoked)、または期限切れ(invite_expired)Error

PUT /v1/orgs/{orgSlug}/members/{userId}

admin 以上が必要です。最後の admin を降格することはできません(409 last_admin)。これは自分自身も含みます。このルールがなければ、組織を管理できる人が誰もいなくなってしまう可能性があり、抜け出す唯一の方法は DB を直接編集することになってしまいます。member.role として監査記録されます。

operationId setMemberRole

リクエストボディ: application/jsonobject

ステータスコード説明レスポンスボディ
200変更されたメンバーMember
400
403
404
409これは最後の admin です(last_admin)Error

DELETE /v1/orgs/{orgSlug}/members/{userId}

他人を削除するには管理者以上の権限が必要ですが、自分自身を削除することは誰にでもできます(userId が自分自身の場合は脱退になります)。もし管理者だけがメンバーを削除できるとしたら、閲覧者として招待された人には org を抜ける方法がなくなってしまいます。

最後の管理者は削除することも脱退することもできません(409 last_admin)。監査ログでは削除は member.remove、脱退は member.leave として記録されます — 同じ操作でもイベントが異なるため、名前も異なります。

operationId removeMember

ステータスコード説明レスポンスボディ
204削除済み
403
404
409これは最後の admin です(last_admin)Error

このページの目次