APIリファレンスと統合のヒント。
CommonRockは認証・セッション・簡易DBを提供し、アプリ側のサーバ実装を最小化します。
CommonRockのAPIは2つの認証方式をサポートしています。エンドポイントによって、片方または両方の方式で呼び出せます。
ブラウザやモバイルアプリから直接呼び出す場合に使用します。
バックエンドサーバから呼び出す場合に使用します。
バックエンドからOpaqueトークンをイントロスペクトします。
curl -X POST /org_demo_payments/v1/sessions/introspect \
-H 'Content-Type: application/json' \
-H 'X-API-Key: sk_live_***' \
-d '{"token":"access_token"}'ブラウザ/ネイティブからは Public Client (X-Client-Id) を、サーバ側からは API Secret Key (X-API-Key) を使います。Public Client で許可する Origin はポータル側で先に設定してください。
// app/api/login/route.ts (Next.js App Router)
// 1. Browser → your Next.js Route Handler
// 2. Route Handler → CommonRock public endpoint with X-Client-Id / X-Client-Key
// 3. Set HttpOnly session cookie back to the browser
import { NextResponse } from "next/server";
const COMMONROCK_BASE = process.env.COMMONROCK_API_BASE_URL!;
const CLIENT_ID = process.env.COMMONROCK_CLIENT_ID!;
const CLIENT_KEY = process.env.COMMONROCK_CLIENT_KEY!;
export async function POST(request: Request) {
const body = await request.json();
const res = await fetch(`${COMMONROCK_BASE}/v1/public/end-users/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Client-Id": CLIENT_ID,
"X-Client-Key": CLIENT_KEY,
Origin: request.headers.get("origin") ?? ""
},
body: JSON.stringify(body)
});
const payload = await res.json();
if (!res.ok) return NextResponse.json(payload, { status: res.status });
const response = NextResponse.json({ ok: true, user: payload.user });
response.cookies.set("cr_at", payload.access_token, {
httpOnly: true,
secure: true,
sameSite: "strict",
maxAge: payload.expires_in
});
return response;
}本番では Public Client / API Secret Key を必ず .env など秘匿化された場所に保管してください。
Route Handler でサーバ側にキーを置き、HttpOnly Cookie でブラウザに返すパターンを推奨。
ネイティブアプリは Public Client + 端末情報を Origin として送る運用。Secret Key は埋め込まない。
サーバ間 API は X-API-Key + allowed_cidrs/allowed_origins で IP 帯を絞ること。
公開APIのリクエスト/レスポンス仕様を詳述します。
ユーザ登録・ログイン・セッション管理
外部IDとパスワードで新規登録し、アクセストークンとリフレッシュトークンを発行します。
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| external_id | string | 必須 | アプリ内ユーザID(最大128文字) |
| password | string | 必須 | 8文字以上 |
| device_id | string | 任意 | 最大128文字。body か X-Device-Id ヘッダで必須 |
curl -X POST /org_demo_payments/v1/public/end-users/signup \
-H 'Content-Type: application/json' \
-H 'Origin: https://app.example.com' \
-H 'X-Client-Id: pk_live_***' \
-H 'X-Client-Key: pk_live_***' \
-d '{"external_id":"user-1","password":"password123","device_id":"iphone-15"}'| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| token | string | 必須 | アクセストークン(Opaque) |
| refresh_token | string | 必須 | リフレッシュトークン |
| end_user.id | uuid | 必須 | エンドユーザID |
| end_user.external_id | string | 必須 | 外部ID |
| session_id | uuid | 必須 | セッションID |
| expires_at | datetime | 必須 | アクセストークン有効期限(ISO8601) |
| refresh_expires_at | datetime | 必須 | リフレッシュ有効期限(ISO8601) |
{
"token":"access_token",
"refresh_token":"refresh_token",
"end_user":{"id":"uuid","external_id":"user-1"},
"session_id":"uuid",
"expires_at":"2026-02-04T13:00:00Z",
"refresh_expires_at":"2026-03-05T13:00:00Z"
}{"detail":"External ID already registered"}外部IDとパスワードでログインし、トークンを再発行します。
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| external_id | string | 必須 | 外部ID |
| password | string | 必須 | パスワード |
| device_id | string | 任意 | 最大128文字。body か X-Device-Id ヘッダで必須 |
curl -X POST /org_demo_payments/v1/public/end-users/login \
-H 'Content-Type: application/json' \
-H 'Origin: https://app.example.com' \
-H 'X-Client-Id: pk_live_***' \
-H 'X-Client-Key: pk_live_***' \
-d '{"external_id":"user-1","password":"password123","device_id":"iphone-15"}'| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| token | string | 必須 | アクセストークン |
| refresh_token | string | 必須 | リフレッシュトークン |
| end_user.id | uuid | 必須 | エンドユーザID |
| end_user.external_id | string | 必須 | 外部ID |
| session_id | uuid | 必須 | セッションID |
| expires_at | datetime | 必須 | アクセストークン有効期限 |
| refresh_expires_at | datetime | 必須 | リフレッシュ有効期限 |
{
"token":"access_token",
"refresh_token":"refresh_token",
"end_user":{"id":"uuid","external_id":"user-1"},
"session_id":"uuid",
"expires_at":"2026-02-04T13:00:00Z",
"refresh_expires_at":"2026-03-05T13:00:00Z"
}{"detail":"Invalid credentials"}リフレッシュトークンでアクセストークンを再発行します。
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| refresh_token | string | 必須 | リフレッシュトークン |
| device_id | string | 任意 | 最大128文字。body か X-Device-Id ヘッダで必須 |
curl -X POST /org_demo_payments/v1/public/end-users/refresh \
-H 'Content-Type: application/json' \
-H 'Origin: https://app.example.com' \
-H 'X-Client-Id: pk_live_***' \
-H 'X-Client-Key: pk_live_***' \
-d '{"refresh_token":"refresh_token","device_id":"iphone-15"}'| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| token | string | 必須 | 新しいアクセストークン |
| refresh_token | string | 必須 | 新しいリフレッシュトークン |
| end_user.id | uuid | 必須 | エンドユーザID |
| end_user.external_id | string | 必須 | 外部ID |
| session_id | uuid | 必須 | セッションID |
| expires_at | datetime | 必須 | アクセストークン有効期限 |
| refresh_expires_at | datetime | 必須 | リフレッシュ有効期限 |
{
"token":"new_access_token",
"refresh_token":"new_refresh_token",
"end_user":{"id":"uuid","external_id":"user-1"},
"session_id":"uuid",
"expires_at":"2026-02-04T13:10:00Z",
"refresh_expires_at":"2026-03-05T13:10:00Z"
}{"detail":"Invalid refresh token"}アクセストークンを失効します。
curl -X POST /org_demo_payments/v1/public/end-users/logout \ -H 'Origin: https://app.example.com' \ -H 'X-Client-Id: pk_live_***' \ -H 'X-Client-Key: pk_live_***' \ -H 'Authorization: Bearer access_token'
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| status | string | 必須 | ok 固定 |
{"status":"ok"}{"detail":"Invalid session"}アクセストークンに紐づくエンドユーザを取得します。
curl /org_demo_payments/v1/public/end-users/me \ -H 'Origin: https://app.example.com' \ -H 'X-Client-Id: pk_live_***' \ -H 'X-Client-Key: pk_live_***' \ -H 'Authorization: Bearer access_token'
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| id | uuid | 必須 | エンドユーザID |
| external_id | string | 必須 | 外部ID |
{"id":"uuid","external_id":"user-1"}{"detail":"Invalid session"}SQLクエリ定義の実行
登録済みSQLクエリ定義を実行してページング取得します。
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| query_definition_id | uuid | 必須 | SQLクエリ定義ID |
| params | object | 任意 | SQLパラメータ |
| limit | int | 任意 | 1〜SQL_MAX_ROWS |
| cursor | string | 任意 | offset or keyset cursor |
| cursor_mode | string | 任意 | offset / keyset (default offset) |
curl -X POST /org_demo_payments/v1/public/sql/execute \
-H 'Content-Type: application/json' \
-H 'Origin: https://app.example.com' \
-H 'X-Client-Id: pk_live_***' \
-H 'X-Client-Key: pk_live_***' \
-H 'Authorization: Bearer access_token' \
-d '{"query_definition_id":"uuid","params":{"author_id":"user-1"},"limit":200}'| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| rows | array | 必須 | 結果行 |
| next_cursor | string | 任意 | 次ページのカーソル |
| warnings[].code | string | 任意 | 警告コード |
| warnings[].message | string | 任意 | 警告メッセージ |
{"rows":[{"id":"uuid","title":"post-1"}],"next_cursor":"200","warnings":[{"code":"order_by_missing","message":"ORDER BY is missing; pagination may be unstable"}]}{"detail":{"code":"client_scope_denied","message":"Operation not allowed for this client"}}セッションイントロスペクション
トークンが有効かを他サーバから検証します。
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| token | string | 任意 | アクセストークン |
| required_scopes | string[] | 任意 | 将来拡張用(現在未使用) |
curl -X POST /org_demo_payments/v1/sessions/introspect \
-H 'Content-Type: application/json' \
-H 'X-API-Key: sk_live_***' \
-d '{"token":"access_token"}'| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| active | boolean | 必須 | 有効なら true |
| project_id | uuid | 任意 | プロジェクトID |
| end_user_id | uuid | 任意 | エンドユーザID |
| session_id | uuid | 任意 | セッションID |
| expires_at | datetime | 任意 | 有効期限 |
{"active":true,"project_id":"uuid","end_user_id":"uuid","session_id":"uuid","expires_at":"2026-02-04T13:00:00Z"}{"detail":{"code":"invalid_api_key","message":"Invalid API key"}}OpenAPI定義を使ってインタラクティブにエンドポイントをテストできます。
多くのAPIは detail 文字列を返します。バリデーションは詳細配列です。
| Code | HTTP | 説明 |
|---|---|---|
| invalid_credentials | 401 | 認証情報が不正 |
| totp_required | 403 | TOTPコードが必要 |
| invalid_totp | 401 | TOTPコードが不正 |
| project_not_found | 404 | プロジェクトが見つからない |
| invalid_cursor | 400 | カーソルが不正 |
| invalid_sql | 400 | SQLが不正 |
| sql_too_complex | 400 | SQL複雑度超過 |
| missing_api_key | 401 | APIキーが未指定 |
| invalid_api_key | 401 | APIキーが不正 |
| restrictions_required | 403 | 制限が未設定 |
| origin_required | 403 | Originヘッダ必須 |
| origin_denied | 403 | Originが許可されていない |
| ip_denied | 403 | IPが許可されていない |
| invalid_public_scopes | 400 | 公開スコープが不正 |
| sql_template_not_found | 404 | SQLテンプレートがない |
| maintenance_mode | 503 | メンテナンス中 |
| csrf_failed | 403 | CSRF検証失敗 |
| rate_limited | 429 | レート制限に到達 |
完全な一覧はリポジトリの docs/error-codes.md を参照してください。
バリデーション (422)
{"detail":[{"loc":["body","field"],"msg":"field required","type":"value_error.missing"}]}シークレットキー認証エラー
{"detail":{"code":"rate_limited","message":"Rate limit exceeded"}}API変更履歴を時系列で掲載します。