仕様・API
公開API・計測キー v0.1
GET /v1/public/lp、POST /v1/analytics/events。
HTTP API v0.1(公開LP・計測)
管理トークン付きの制作API は manage-api-v0.1.md(Workspace / LP / メディアアップロード等)。
ここでは 埋め込み/ZIPランタイム が呼ぶ 公開エンドポイント と publicKey(計測キー) の契約を定義する。
関連: embed-and-zip-v0.1.md、lp-definition-v0.1.md、analytics-events-v0.1.md。
共通
ベースURL
クライアントの apiBase(例: https://api.example.com)。末尾スラッシュなし。パスは常に /v1/... から始める。
形式
- リクエスト/レスポンスボディは JSON、
Content-Type: application/json; charset=utf-8。 - 日時は ISO8601 UTC(
Z)。
CORS
GET /v1/public/lp/*… 任意オリジンからの GET を許可してよい(LPは公開前提)。POST /v1/analytics/events… 計測キー送信を伴う。X-SwipeLP-Keyを許可ヘッダに含める。OPTIONSプリフライトに応答すること。
エラー形式(推奨)
失敗時は次の形を推奨(必須ではないが、実装間で揃える)。
{
"error": {
"code": "not_found",
"message": "LPが見つかりません"
}
}
| HTTP | code 例 | 用途 |
|---|---|---|
| 400 | invalid_request | JSON不正・バリデーション |
| 401 | invalid_key | 計測キー不正・欠落(POST計測のみ) |
| 403 | key_lp_mismatch | キーは有効だが当該 lpId に紐づかない |
| 404 | not_found | LP不存在 |
| 410 | gone | 公開停止済み |
| 429 | rate_limited | レート制限 |
| 500 | internal_error | サーバ障害 |
GET /v1/public/lp-preview/{token}
仮公開(管理画面の「仮公開URL」)用。POST /v1/manage/.../preview-share で発行した token のスナップショットを返す。本番の公開状態とは別(未公開LPでも閲覧可)。認証不要。
レスポンス 200
GET /v1/public/lp/{lpId} と同じ形(definition / revision / updatedAt)。
失敗
| HTTP | 条件 |
|---|---|
| 404 | トークン不明 |
| 410 | 有効期限切れ |
GET /v1/public/lp/{lpId}
公開状態のLP定義を返す。認証ヘッダ不要(URLの lpId のみ)。
パスパラメータ
| 名前 | 説明 |
|---|---|
lpId | LP定義の id(公開ID)。 |
レスポンス 200
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
definition | object | ✓ | lp-definition-v0.1.md 準拠。 |
revision | string | ✓ | サーバが公開しているリビジョン。definition.revision と原則同一。異なる場合はクライアントは 定義内 revision を優先(embed-and-zip-v0.1.md)。 |
updatedAt | string | 公開設定または定義の最終更新(任意)。 | |
publicKey | string | 本番計測用の pk_live_*(公開時にサーバが未設定なら自動発行)。ホスト型閲覧・埋め込みの X-SwipeLP-Key に使う。 |
例:
{
"definition": {
"schemaVersion": "0.1",
"id": "01JRQEXAMPLELPID00",
"revision": "3",
"meta": { "title": "キャンペーン", "locale": "ja-JP" },
"swipe": { "direction": "vertical", "viewport": "default" },
"steps": []
},
"revision": "3",
"updatedAt": "2026-04-15T08:00:00.000Z",
"publicKey": "pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
失敗
| HTTP | 条件 |
|---|---|
| 404 | lpId が存在しない。 |
| 410 | 存在するが 非公開(削除・公開停止)。 |
| 429 | レート制限。Retry-After を付与してよい。 |
POST /v1/analytics/events
analytics-events-v0.1.md のイベントをバッチ送信する。
ヘッダ
| ヘッダ | 必須 | 説明 |
|---|---|---|
Content-Type | ✓ | application/json |
X-SwipeLP-Key | ✓ | 計測用 公開キー(後述)。 |
キー未送信・空は 401。
ボディ
{
"events": [
{
"eventId": "uuid",
"name": "step_view",
"occurredAt": "2026-04-15T12:00:00.000Z",
"sessionId": "…",
"surface": "embed",
"lpId": "01JRQEXAMPLELPID00",
"revision": "3",
"payload": { }
}
]
}
| フィールド | 必須 | 制約 |
|---|---|---|
events | ✓ | 1〜100件。超過は 400。 |
各イベントの内容は analytics-events v0.1 に準拠。サーバは次を検証する:
events[].lpIdがキーに紐づくLPと一致すること(不一致は 403)。name・必須フィールド・型がスキーマに合うこと(不正は 400)。- 重複
eventIdは冪等に捨ててよい(推奨)。
レスポンス
| HTTP | 意味 |
|---|---|
| 204 | 受理(ボディなし) |
| 202 | 受理(非同期キューに入れた場合など。ボディ任意) |
失敗時は上記エラー形式。
レート制限
- IP および 公開キー 単位で上限を設けてよい(例: 分あたりリクエスト数・イベント数)。
- 429 時は
Retry-Afterを推奨。
計測キー(publicKey)v0.1
目的
- 匿名の計測POST を許可するが、どのLPに紐づくトラフィックかを識別し、キー漏洩時は失効できるようにする。
文字列形式(確定)
pk_{environment}_{opaque}
| 部分 | 説明 |
|---|---|
pk_ | 固定プレフィックス。 |
environment | live | test(本番・検証)。 |
opaque | サーバ生成のランダム文字列(例: Base62、長さ 24文字以上 を推奨)。 |
例: pk_live_xK9mN2pQvR8sT4uVwXyZaBcDeFgHiJkLmNoPqRsTu
- 秘密鍵方式にしない(クライアントに置くため)。サーバ側では ハッシュのみ保存(後述)。
- 人間が読む意味は持たない(Workspace ID を埋め込まない)。
発行
- 管理API(別文書)で、Workspace 管理者が LP単位 または Workspace 単位 でキーを発行(MVPは LP単位 を推奨:漏洩影響を最小化)。
- サーバは
opaqueを生成し、平文は一度だけ UI に表示(以降は再表示しない)。 - DBには
HMAC-SHA256(secret_pepper, pk_live_...)などの ハッシュ のみ保存。secret_pepperは環境変数。
検証(POST /v1/analytics/events)
X-SwipeLP-Keyを読み、形式がpk_{live|test}_*でなければ 401。- 同じ規則でハッシュを計算し、登録キーと照合。なければ 401。
- キーに紐づく
lpId(または複数LPを許す場合は集合)と、ボディ内の各events[].lpIdが一致するか確認。1件でも不一致なら 403。 environmentがtestのキーは、本番Workspaceの本番LPに流さないなど、ポリシーをサーバで分けてよい。
失効・ローテーション
- 管理画面から 無効化 可能にする。無効キーは 401。
- 同一LPに 複数キー を許可し、入れ替え期間を持てるとよい(旧キーに短い猶予)。
クライアントへの埋め込み
- 埋め込みHTML / ZIP
swipe-lp.config.jsonに 平文で置く(仕様上やむをなし)。 - 管理画面では再表示不可・漏洩時は失効、を運用ルールに書く。
v0.2 候補
- 管理API(LP CRUD、キー発行、Workspace)
GET /v1/public/lp/{lpId}の ETag / If-None-Match(キャッシュ)- 計測の バルク圧縮(
Content-Encoding: gzip)