取り込み API
Creative Survey(CS)の既存調査票を取り込むエンドポイント。Chrome 拡張から呼び出されます。
取り込まれたデータは外部データ用テーブル群(external_*)に生の構造のまま保存され、あわせて質問ライブラリの「外部由来データ」として登録されます。
レスポンス形式・エラーの扱いは API 定義 を参照。
メソッド
HTTP メソッド
| メソッド | URI | 概要 |
|---|---|---|
| POST | /api/imports/creative-survey/bundle |
Creative Survey bundle インポート |
| GET | /api/imports/creative-survey/existing-ids |
取込済み externalId 一覧 |
| GET | /api/imports/creative-survey/section-previews |
セクション候補プレビュー(全件) |
| GET | /api/imports/creative-survey/section-previews/{externalSurveyId} |
セクション候補プレビュー(単一) |
認証要件
/api/imports/* は通常のユーザーヘッダ認証に加えて、API キー認証 が使えます。
| 方式 | 条件 |
|---|---|
| ユーザーヘッダ | x-user-email + x-user-name |
| API キー | 環境変数 SURVEY_IMPORT_API_KEY が設定されており、x-api-key ヘッダの値が一致する |
API キー認証では、x-user-email が併せて指定されていればそのユーザーとして、未指定なら import-bot@local(表示名 Import Bot)として取り込み履歴が記録されます。
Creative Survey bundle インポート
概要
Chrome 拡張が CS の API から取得した調査票データ(bundle JSON)を受け取り、外部データテーブル群へ保存します。
同じ調査票(source + externalId の組)がすでに存在する場合は、連鎖削除してから再投入 します。取り込みを何度実行しても重複しません。
URI
リクエストヘッダー
Content-Type:application/jsonx-api-key:<SURVEY_IMPORT_API_KEY>(API キー認証の場合)
リクエストボディ
{
"fetchedAt": "2026-08-18T00:00:00.000Z",
"origin": "https://4dsd.svy.ooo",
"summary": {},
"surveys": [
{
"surveyId": 12345,
"surveyMeta": {},
"survey": { "name": "既存の調査票" },
"questionnaire": { "id": 1, "survey_id": 12345, "generate_order": [[101, 102]] },
"questions": [
{
"id": 101,
"answer_type": 2,
"answer_type_name": "選択",
"rendered_sentence": "あなたの性別をお答えください。",
"order_index": 0,
"any_logic": true,
"any_visibility": false,
"answer_items": [{ "id": 1001, "sentence": "男性", "order_index": 0 }],
"sub_items": [],
"logics": [
{
"id": 5001,
"order_index": 0,
"logic_items": [
{ "id": 9001, "question_id": 101, "answer_item_id": 1001, "verb": 0, "value": "" }
],
"logic_action": { "id": 7001, "question_id": 105, "is_random": false }
}
]
}
],
"errors": []
}
]
}
バリデーションルール
| フィールド | ルール |
|---|---|
| origin | 必須。1 文字以上の文字列 |
| surveys | 必須。1 件以上の配列 |
| surveys[].surveyId | 必須。数値(CS 側の調査票 ID) |
| surveys[].survey | 必須。オブジェクトまたは null |
| surveys[].questionnaire | 必須。オブジェクトまたは null |
| surveys[].questions | 任意。設問の配列 |
| fetchedAt / summary / errors | 任意 |
設問・選択肢・分岐の各オブジェクトは 未知のフィールドをそのまま通します(CS の API 仕様が非公開のため、想定外のフィールドも生の JSON として保存する)。
レスポンス(200 OK)
{
"ok": true,
"data": {
"surveysImported": 1,
"questionsImported": 24,
"answerItemsImported": 130,
"subItemsImported": 12,
"logicsImported": 8,
"logicItemsImported": 15,
"libraryItemsImported": 24,
"surveyIds": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"],
"skipped": []
}
}
| フィールド | データ型 | 備考 |
|---|---|---|
| surveysImported | number | 取り込んだ調査票の件数 |
| questionsImported | number | 取り込んだ設問の件数 |
| answerItemsImported | number | 取り込んだ選択肢の件数 |
| subItemsImported | number | 取り込んだサブ項目の件数 |
| logicsImported | number | 取り込んだ分岐ロジックの件数 |
| logicItemsImported | number | 取り込んだ分岐条件の件数 |
| libraryItemsImported | number | 質問ライブラリへ登録した件数 |
| surveyIds | string[] | 保存された external_surveys の UUID 配列 |
| skipped | object[] | 取り込まなかった調査票(externalId と reason) |
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
リクエストボディが不正(surveys が空、origin が空など) |
400 | Bad Request |
| 認証情報がない、または API キーが不一致 | 401 | Unauthorized |
処理フロー
シーケンス図
sequenceDiagram
participant Ext as Chrome 拡張
participant API
participant DB
participant Library as 質問ライブラリ
Ext->>API: POST /api/imports/creative-survey/bundle
API->>API: リクエストバリデーション
API->>API: 実行ユーザーを解決 (API キーなら Import Bot)
loop 調査票ごと
API->>DB: (source, externalId) の既存を検索
opt 既存あり
API->>DB: 既存の external_surveys を削除 (配下は連鎖削除)
end
API->>DB: external_surveys へ保存
API->>DB: external_questions へ保存
API->>DB: external_answer_items / external_sub_items へ保存
API->>DB: external_logics / external_logic_items へ保存
API->>Library: 各設問を外部由来データとして登録
end
API->>API: 取り込み件数を集計
API-->>Ext: 200 OK
取込済み externalId 一覧
概要
すでに取り込み済みの CS 調査票 ID の一覧を返します。
Chrome 拡張が中断した取り込みを再開する際、取得済みの調査票をスキップするために使います。
URI
クエリパラメータ
| パラメータ | データ型 | 必須 | 備考 |
|---|---|---|---|
| source | string | 取得元の識別子。既定は creative_survey |
レスポンス(200 OK)
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
| 認証情報がない | 401 | Unauthorized |
セクション候補プレビュー(全件)
概要
取り込み済みのすべての外部調査票について、セクション候補 を返します。
CS にはセクション(大問)の概念がないため、設問の並びを answer_type_name が「提示ステップ」の設問で区切って セクション候補に分割します。
URI
レスポンス(200 OK)
{
"ok": true,
"data": [
{
"externalSurveyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"externalSurveyName": "既存の調査票",
"externalSurveyExternalId": 12345,
"sections": [
{
"index": 0,
"title": "スクリーニング",
"description": "",
"libraryItemIds": ["…", "…"],
"questionCount": 5
}
]
}
]
}
| フィールド | データ型 | 備考 |
|---|---|---|
| sections[].index | number | セクション候補の位置 |
| sections[].title | string | 区切りとなった提示ステップの文言から導出したタイトル |
| sections[].libraryItemIds | string[] | このセクションに含まれる質問ライブラリの UUID 配列 |
| sections[].questionCount | number | 設問数 |
ここで得た libraryItemIds を セクション API の「外部由来から 1 セクション一括挿入」 に渡すと、1 セクションとしてまとめて挿入できます。
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
| 認証情報がない | 401 | Unauthorized |
セクション候補プレビュー(単一)
概要
指定した外部調査票 1 件分のセクション候補を返します。
URI
| パラメータ | データ型 | 必須 | 備考 |
|---|---|---|---|
| externalSurveyId | string | ◯ | external_surveys の UUID |
バリデーションルール
| フィールド | ルール |
|---|---|
| externalSurveyId | 必須。UUID 形式 |
レスポンス(200 OK)
1 調査票分のセクション候補を返します(構造は一覧版の要素と同じ)。
例外処理
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
externalSurveyId が UUID 形式でない |
400 | Bad Request |
| 指定した外部調査票が存在しない | 404 | Not Found |