Admin API

対象読者:管理 backend、developer console、または integration test を作る開発者。

admin API は contracts version 0.4.0-alpha.1 に対応し、ローカルでは http://localhost:4100 で提供されます。project key ではなく、developer JWT bearer auth を使います。現在の Alpha は developer 登録/ログイン、organization/project、project key、invitation、feedback list/detail、attachments、status と priority 更新、comments、audit logs をサポートします。

Developer Console とすべての management client は /admin/v1/* を使います。削除済みの Admin /v1/* compatibility path は 404 を返します。Public API は別 service であり、その /v1/* route は引き続き canonical です。

seed または bootstrap で作成された system admin に追加される system-wide capability は、全ユーザーの基本 profile fields を確認する read-only の /admin/v1/system/users だけです。system_admin は account の user_type であり、organization または project の認可を迂回しません。すべての tenant API は、対象 organization または project における実際の membership role(owneradmindeveloperqaviewer)で認可されます。membership がなければ対象を指定した tenant request は 403 となり、collection と Developer Graph にもその tenant は含まれません。新しい organization の作成時には、作成者の owner membership が同時に作られます。

組織とプロジェクトへのアクセスにはメール確認が必要です。JWTは実際のサーバーセッションに結び付きます。通常のログアウトは現在のセッションを、全ログアウト・パスワード変更/再設定・無効化・退会は対象の全セッションを失効させます。旧Alphaのアカウントとデータは移行しません。詳細はアカウントとセキュリティを参照してください。

ルートマップ

/admin/v1/* が唯一の management namespace です。

領域 Canonical route
データのライフサイクル POST /admin/v1/feedback/reports/{report_id}/deletion, POST /admin/v1/projects/{project_id}/deletion, POST /admin/v1/organizations/{organization_id}/deletion, GET /admin/v1/data-deletions/{deletion_id}, POST /admin/v1/projects/{project_id}/export
Liveness / readiness GET /healthz, GET /readyz
Auth POST /admin/v1/auth/register, POST /admin/v1/auth/login, POST /admin/v1/auth/logout, GET /admin/v1/auth/me , POST /admin/v1/auth/verification/request, POST /admin/v1/auth/verification/confirm, POST /admin/v1/auth/password/reset/request, POST /admin/v1/auth/password/reset/confirm, POST /admin/v1/auth/password/change, POST /admin/v1/auth/logout-all, POST /admin/v1/auth/account/delete
Developer graph GET /admin/v1/developer-graph
Organizations GET|POST /admin/v1/organizations, GET|PATCH /admin/v1/organizations/{organization_id}, GET /admin/v1/organizations/{organization_id}/members, PATCH|DELETE /admin/v1/organizations/{organization_id}/members/{user_id}
Organization invitations GET|POST /admin/v1/organizations/{organization_id}/developer-invitations, POST /admin/v1/organizations/{organization_id}/developer-invitations/{invitation_id}/revoke, POST /admin/v1/invitations/accept
Projects GET|POST /admin/v1/projects, GET|PATCH /admin/v1/projects/{project_id}, GET /admin/v1/projects/{project_id}/overview
Project members and invitations GET /admin/v1/projects/{project_id}/members, PATCH|DELETE /admin/v1/projects/{project_id}/members/{user_id}, GET|POST /admin/v1/projects/{project_id}/invitations, POST /admin/v1/projects/{project_id}/invitations/{invitation_id}/revoke
Project keys GET|POST /admin/v1/projects/{project_id}/keys, POST /admin/v1/projects/{project_id}/keys/{key_id}/revoke
Feedback GET /admin/v1/feedback/reports, GET|PATCH /admin/v1/feedback/reports/{report_id}
Feedback comments GET|POST /admin/v1/feedback/reports/{report_id}/comments
Attachments GET /admin/v1/feedback/reports/{report_id}/attachments, GET /admin/v1/feedback/reports/{report_id}/attachments/{attachment_id}/download-url
Audit and users GET /admin/v1/audit-logs, GET /admin/v1/system/users

添付ダウンロード endpoint は、signed URL をラップせず、正確なトップレベル object { "url": "https://...", "expires_at": "<RFC3339>" } を返します。

path の report_id は現在の実装上の feedback report ID で、product-level GOAL text の feedback_id と同じ値です。

Project Key 作成 response は { "key": { ...masked metadata... }, "plaintext_key": "enb_pk_..." } です。plaintext_key は一度だけ copy し、list/revoke response は masked key object のみを返します。response field に project_key は使いません。

現在のすべてのKeyは保存済みの4文字の last_four を含みます。末尾情報のない旧データはサポートしません。コメントと監査には author_deletedactor_deleted があり、退会済みの個人情報は空、画面表示は「退会したユーザー」です。退会により消去した招待先メールは履歴でのみ空になり、未承諾の招待では空にできません。

organization owner はすべての member role を変更して owner を付与できます。organization admin は owner 以外の member の変更・削除だけが可能で、owner は付与できません。最後の owner を降格または削除すると 409 admin.organization_member.last_owner が返ります。同じ role への PATCH は idempotent です。organization membership を削除しても、その user の direct project membership は削除されません。成功した role change と removal は organization_member.role_updated または organization_member.removed audit を記録し、拒否または no-op request は記録しません。

ページングと安定ソート

12 個の canonical list GET はすべて limitoffset を受け取り、正確な top-level { items, offset, limit, total, has_more } envelope を返します。cursornext_cursor、nested paginationcountnext_offset は返しません。

{
  "items": [],
  "offset": 0,
  "limit": 50,
  "total": 0,
  "has_more": false
}

limit を省略すると 50 で、有効範囲は 1 から 100 です。offset を省略すると 0 で、負数は指定できません。明示的な空値、重複 parameter、整数でない値、範囲外の値は 400 admin.request.invalid を返します。total は tenant authorization と business filter の適用後、offset/limit の適用前の件数です。has_more はその filter 結果に次の page があるかだけを示します。total を超える有効な offset は error ではなく、空の items とともに 200 を返します。

List GET 固定順序
/admin/v1/organizations name ASC, id ASC
/admin/v1/organizations/{organization_id}/members email ASC, user_id ASC
/admin/v1/organizations/{organization_id}/developer-invitations created_at DESC, id DESC
/admin/v1/projects name ASC, id ASC
/admin/v1/projects/{project_id}/members email ASC, user_id ASC
/admin/v1/projects/{project_id}/invitations created_at DESC, id DESC
/admin/v1/projects/{project_id}/keys created_at DESC, id DESC
/admin/v1/feedback/reports received_at DESC, id DESC
/admin/v1/feedback/reports/{report_id}/attachments created_at ASC, id ASC
/admin/v1/feedback/reports/{report_id}/comments created_at ASC, id ASC
/admin/v1/audit-logs created_at DESC, id DESC
/admin/v1/system/users email ASC, id ASC

feedback list がサポートする filter は project_idstatuscategory、case-insensitive の search だけで、search は title/description に一致します。Developer Graph は current user、visible organization、project、membership をまとめて返す navigation aggregate です。この 12 個の list GET には含まれず、pagination parameter を受け取りません。

組織設定

PATCH /admin/v1/organizations/{organization_id} は、必須の name だけを含む 1 つの JSON object を受け取ります。変更するのは表示名だけです。field の欠落、未知または重複した field、slug などの追加 field は 400 admin.organization.invalid になります。organization ID と slug は変更されません。

service は最初に元の name が 120 Unicode code point 以下であることを検証し、その後に前後の Unicode whitespace を除去します。正規化後の name は空にできません。大小文字と内部 whitespace は保持されます。organization name は一意である必要がなく、別 organization と同じ正規化済み name でも 409 にはなりません。

この organization に明示的な owner または admin membership を持つ caller だけが name を変更できます。developerqaviewer member は 403 です。system_admin account に tenant bypass はなく、明示的な owner または admin membership が必要です。正規化後の no-op は完全な現在の { "organization": ... } とともに 200 を返し、updated_at を変更せず、audit event も記録しません。実際の変更では organization update とちょうど 1 件の organization.name_updated event を atomically に記録します。この event は organization を target とし、project_id を持たず、metadata は正確に { "old_name": ..., "new_name": ... } です。

bearer token と organization ID は local environment variable に入れ、secret を command や document に埋め込まないでください:

ADMIN_API="${ADMIN_API:-http://localhost:4100}"
: "${ACCESS_TOKEN:?先に ACCESS_TOKEN を export してください}"
: "${ORG_ID:?先に ORG_ID を export してください}"

curl --fail-with-body -X PATCH "$ADMIN_API/admin/v1/organizations/$ORG_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept-Language: ja" \
  -d '{"name":"Echo Nebula スタジオ"}'

プロジェクト設定

PATCH /admin/v1/projects/{project_id}namedefault_localedefault_environmentsdk_features を更新します。request にはこのうち少なくとも 1 field が必要で、それ以外の top-level field は拒否されます。省略した値はすべて現在値のままです。namedefault_environment は前後の空白を除去し、大小文字は保持します。default_locale は正確に zh-CNenja のいずれかである必要があり、空白除去や大小文字の正規化は行いません。

sdk_features を指定した場合は完全置換 object となり、boolean の screenshotrecent_logsbreadcrumbsoffline_queuecontact をすべて指定する必要があります。一部だけの feature object は無効です。slug は read-only で PATCH には指定できず、project name を変更しても slug は変わりません。

設定を更新できるのは effective project role が owner または admin の caller、つまり organization owner/admin または direct project admin だけです。system_admin だけではアクセスできません。Developer、QA、viewer は 403 です。無効、空、未知の field は 400 admin.project.invalid、存在しない project は 404 admin.project.not_found となり、この operation に 409 case はありません。

正規化後の no-op は現在の完全な { "project": ... } とともに 200 を返し、updated_at を変更せず、audit event も記録しません。1 つ以上の実変更は atomically に反映され、1 件の project.updated を記録します。metadata は canonical order の changed_fields と、実際に変わった field だけを含む before / after を持ちます。SDK feature の変更では両側に完全な 5 field object を記録します。

curl -X PATCH "http://localhost:4100/admin/v1/projects/proj_demo" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -H "Accept-Language: ja" \
  -d '{
    "name": "Echo Arena",
    "default_locale": "ja",
    "default_environment": "Production",
    "sdk_features": {
      "screenshot": true,
      "recent_logs": false,
      "breadcrumbs": true,
      "offline_queue": true,
      "contact": false
    }
  }'

Liveness、readiness、ブラウザアクセス

GET /healthz は Admin API process が応答できることだけを示します。認証不要の GET /readyz は、制限時間内に PostgreSQL と設定済み object-storage bucket を確認します。

HTTP 全体 PostgreSQL Object storage 意味
200 ready ready ready Tenant data と attachment operation が利用可能です。
200 degraded ready degraded Text management は利用できますが、attachment operation は失敗する可能性があります。
503 unavailable unavailable ready または degraded Admin API は tenant data を提供できません。

すべての readiness response は Cache-Control: no-store を使い、statusservice、2 つの component status だけを返します。dependency error、endpoint、bucket name、credential は公開しません。

ブラウザアクセスは exact-origin の ADMIN_CORS_ALLOWED_ORIGINS list で制御します。許可された Origin は Access-Control-Allow-Origin にそのまま返され、不一致、wildcard-like、null Origin は 403 になります。response は Vary: Origin を含み、credentialed CORS は有効にしません。Origin header のない non-browser client は引き続き利用できます。Bearer token は Authorization header で送ります。

最小例

curl -X POST "http://localhost:4100/admin/v1/auth/register" \
  -H "Content-Type: application/json" \
  -H "Accept-Language: ja" \
  -d '{
    "email": "new-developer@example.test",
    "password": "change-me-123",
    "display_name": "Demo Developer",
    "preferred_locale": "ja"
  }'

curl -X POST "http://localhost:4100/admin/v1/auth/verification/confirm" \
  -H "Content-Type: application/json" \
  -d '{"email":"new-developer@example.test","password":"change-me-123","code":"<8-digit email code>"}'

curl -X POST "http://localhost:4100/admin/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "new-developer@example.test",
    "password": "change-me-123"
  }'

curl "http://localhost:4100/admin/v1/feedback/reports?project_id=proj_demo&status=new&category=bug&search=stuck&limit=50&offset=0" \
  -H "Authorization: Bearer <access_token>"

curl -X POST "http://localhost:4100/admin/v1/feedback/reports/fbr_demo/comments" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"body":"QA がスクリーンショットの文脈を確認しました。"}'

curl "http://localhost:4100/admin/v1/audit-logs?project_id=proj_demo" \
  -H "Authorization: Bearer <access_token>"

curl "http://localhost:4100/admin/v1/audit-logs?organization_id=org_demo" \
  -H "Authorization: Bearer <access_token>"

contracted feedback statuses は newreviewingresolvedignoredarchived です。 contracted feedback priorities は unsetlowmediumhighurgent です。

よくある間違い

次のステップ

開発者ユーザーグラフと招待を確認してください。

リソース制限と起動設定ポリシーはトラブルシューティングを参照してください。

データのライフサイクル