連携APIの説明
受入れ企業から鍵を受け取った監理団体・送り出し機関・教材会社のシステムが、学習の進み具合と確認済みの用語集を読み書きできます。どの学習者の情報も、本人が共有に同意した分だけです。
OpenAPI の定義(/api/partner/v1/openapi.json)
鍵と呼び出しの決まり
- 受入れ企業の管理者が発行した鍵を Authorization: Bearer で送ります。
- 鍵ごとに見てよい範囲(スコープ)と対象の言語が決まっています。
- 1本の鍵で1分に60回まで。超えると 429 と Retry-After を返します。
- 作成・更新(POST・PUT)には Idempotency-Key ヘッダーが必要です。同じキーなら同じ応答を返します(24時間)。
- 一覧は limit(最大100、既定50)と cursor でページを送ります。
- 日時は +09:00 付きの ISO 8601 です。
エンドポイント
| メソッド | パス | スコープ | 概要 |
|---|---|---|---|
GET | /api/partner/v1/ping | (鍵があれば可) | 鍵の確認 |
GET | /api/partner/v1/openapi.json | (なし) | OpenAPI 3.1 の定義 |
GET | /api/partner/v1/learners | learners:read | 本人が共有に同意している学習者の一覧と進み具合。名前は pii:read かつ組織の設定がオンのときだけ |
GET | /api/partner/v1/learners/{learner_id}/progress | learners:read | 1人の進み具合・最近の小テスト10回・間違いの多い言葉(最大5語) |
GET | /api/partner/v1/glossary/terms | glossary:read | 会社の現場用語集(確認済みの訳だけ) |
POST | /api/partner/v1/glossary/terms | glossary:write | 用語の取り込み(1回100語まで。必ず下書きとして入る) |
GET | /api/partner/v1/glossary/rules | glossary:read | 訳し方の決まり(訳さない言葉・訳を固定する言葉) |
PUT | /api/partner/v1/glossary/rules | glossary:write | 訳し方の決まりの取り込み(1回200件まで) |
GET | /api/partner/v1/templates | templates:read | SBGGが承認した業種別テンプレートの一覧 |
GET | /api/partner/v1/templates/{template_id} | templates:read | テンプレートの中身(カードと確認済みの訳) |
イベント(Webhook)
learner.test_passed | 学習者が小テストで80点以上を取ったとき(本人が共有に同意している場合だけ)。名前は入れません。 |
|---|---|
card.native_approved | 確認者がカードのインドネシア語またはベトナム語の訳を承認したとき(修正して承認を含む)。 |
glossary.updated | 用語の取り込み・テンプレートの追加・カードのアーカイブ・訳し方の決まりの変更のとき(1回の操作で1件)。 |
イベントの届く順番は保証しません。created_at で判断してください。
{"id":"evt_tp_c1d2e3f4-0000-4000-8000-000000000003","type":"learner.test_passed","created_at":"2026-09-20T20:05:00+09:00","org_id":"0f0e...","data":{"learner_id":"7b0e1c52-...","attempt_id":"c1d2e3f4-...","lang":"id","job_type":"manufacturing","score":90,"correct":9,"total":10,"first_pass":true,"finished_at":"2026-09-20T20:05:00+09:00","days_to_first_pass":18}}署名の確かめ方
- ヘッダー X-SBGG-Signature は t=<UNIX秒>,v1=<署名> の形です。
- 署名は、登録のときに表示した署名用の秘密で、「t + . + 本文」を HMAC-SHA256 で計算した16進数です。
- t が今の時刻から300秒以上ずれていたら捨ててください。
- 失敗したときは 1分→5分→30分→2時間→12時間 の間隔で最大6回送ります。
// Node.js
import crypto from 'node:crypto';
function verify(secret, rawBody, header) {
const [, t, v1] = header.match(/^t=(\d+),v1=([0-9a-f]{64})$/) ?? [];
if (!t || Math.abs(Date.now() / 1000 - Number(t)) >= 300) return false;
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}エラーの形
{"error":{"code":"invalid_request","message":"The request is invalid.","details":[{"path":"terms[0].term_ja","issue":"too_long"}]}}400 invalid_request400 idempotency_key_required401 unauthorized403 forbidden404 not_found409 idempotency_conflict422 card_limit429 rate_limited
個人情報
学習者の名前は、鍵に pii:read があり、組織の設定がオンで、本人が共有に同意しているときだけ返します。
在留カード番号・パスポート番号・在留資格の項目はありません。未知の項目を送ると 400 になります。
curl の例
curl -H "Authorization: Bearer gb_live_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ https://genba-kotoba.com/api/partner/v1/ping
curl -H "Authorization: Bearer $GENBA_KEY" \ "https://genba-kotoba.com/api/partner/v1/learners?lang=id&limit=50"
curl -X POST -H "Authorization: Bearer $GENBA_KEY" \
-H "Idempotency-Key: 2026-10-01-import-001" \
-H "Content-Type: application/json" \
-d '{"terms":[{"term_ja":"玉掛け","meaning_ja":"クレーンで吊る荷物にワイヤーを掛けること","category":"safety"}]}' \
https://genba-kotoba.com/api/partner/v1/glossary/terms