認証
API キーを取得すべての呼び出しで、Authorization ヘッダーに Bearer トークンを付けます。Sofia は呼び出しのたびにトークンの背後にある権限を確認します。Workspace から外されたユーザーや取り消された認可のトークンは、次のリクエストで無効になります。
| 方式 | 用途 | トークン |
|---|---|---|
| 個人キー | 自分のアカウントの自動化、スクリプト、エージェント | sofia_pk_live_…、有効期限まで有効 |
| OAuth、認可コード + PKCE | ユーザーが選んだ Workspace で、ユーザーの代わりに動作する製品 | sofia_live_at_…、1 時間、更新可能 |
| OAuth、クライアントクレデンシャル | 自分が所有する Workspace を自動化する自社サーバー | sofia_live_at_…、1 時間 |
個人キー
設定 › API › 個人アクセスでキーを作成します。キーはあなたのすべての Workspace であなたの代わりに動作します。指定した店舗が Workspace を決め、そこでのあなたのロールがキーにできることを決めます。
curl https://api.sofia-post.com/api/v1/establishments \
-H "Authorization: Bearer sofia_pk_live_…"OAuth:PKCE 付き認可コード
設定 › API › アプリクライアントでクライアントを登録します。名前、ロゴ、プライバシーポリシー、要求できる権限、https のリダイレクト URL を設定します。confidential クライアントにはシークレットがあります。public クライアント(モバイルアプリ、ブラウザ拡張機能)にはシークレットがなく、PKCE のみに頼ります。
PKCE チャレンジ(S256 は必須)と、ユーザーのセッションに保存しておく state を付けて、ユーザーを認可エンドポイントへ誘導します。
import { createHash, randomBytes } from 'node:crypto';
const verifier = randomBytes(32).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
const state = randomBytes(16).toString('base64url');
const url = new URL('https://api.sofia-post.com/api/v1/oauth/authorize');
url.search = new URLSearchParams({
response_type: 'code',
client_id: process.env.SOFIA_CLIENT_ID,
redirect_uri: 'https://app.example.com/oauth/callback',
scope: 'establishments:read posts:read posts:write offline_access',
state,
code_challenge: challenge,
code_challenge_method: 'S256',
}).toString();ユーザーは Sofia にサインインし、あなたの名前、ロゴ、権限を確認して、Workspace を選択し、承認します。Sofia は code、あなたの state、発行者 iss を付けて、ユーザーをリダイレクト URL に戻します。state と iss を確認してから、コードを交換します。
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
-u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
-d grant_type=authorization_code \
-d code=$CODE \
-d redirect_uri=https://app.example.com/oauth/callback \
-d code_verifier=$VERIFIER{
"access_token": "sofia_live_at_…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "establishments:read posts:read posts:write offline_access",
"refresh_token": "sofia_live_rt_…"
}- コードの有効期間は 5 分で、1 回限りです。再利用すると拒否され、そのコードで発行されたトークンも無効になります。
- アクセストークンの有効期間は 1 時間で、ユーザーが選んだ Workspace に対してのみ動作します。
refresh_tokenは、offline_accessを要求した場合のみ返されます。1 回限りの使用です。そのたびに新しいものを保存してください。使用済みのリフレッシュトークンを再利用すると、認可全体が取り消されます。
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
-u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
-d grant_type=refresh_token \
-d refresh_token=$REFRESH_TOKENOAuth:クライアントクレデンシャル
confidential クライアントは、ユーザーを介さずに、所有者が所有する Workspace を操作することもできます。クライアントが複数の Workspace を持つ場合は、workspace_id で 1 つ指定します。
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
-u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
-d grant_type=client_credentials \
-d workspace_id=$WORKSPACE_ID権限(スコープ)
| スコープ | 許可される操作 |
|---|---|
establishments:read | 店舗の一覧表示 |
accounts:read, accounts:write | 連携済みネットワークの取得、連携リンクの作成 |
media:read, media:write | メディアライブラリの取得、メディアのアップロードとインポート |
posts:read, posts:write | 投稿の一覧表示と追跡、投稿の公開・編集・削除 |
insights:read | 統計の取得 |
webhooks:read, webhooks:write | webhook の一覧表示、登録・テスト・削除 |
offline_access | OAuth のみ:リフレッシュトークンの受け取り |
必要なスコープがない呼び出しは 403 insufficient_scope で応答されます。サーバーメタデータ(RFC 8414)に、すべてのエンドポイントとスコープが記載されています。
https://api.sofia-post.com/.well-known/oauth-authorization-server/api/v1/oauth