オペレーションポーリング
このAPIサーフェスは、Roktネットワーク上に構築する統合パートナー向けです。Roktのeコマースパートナーで、自分のチェックアウトに配置を統合する場合は、代わりにRokt Ecommerce開発者ドキュメントを使用してください。
すべての書き込みレスポンスにはX-Operation-Idヘッダーが含まれています。それをキャプチャしてください。HTTPクライアントがレスポンスを読み取る前にタイムアウトした場合、GET /v1/partnership/operations/{operation_id}をポーリングすることで元の結果を復旧できます。サーバーサイドのステートマシンには、元の書き込みの完全なレスポンスボディを含む正規の記録があります。
ポーリングが重要な場合ポーリングが重要な場合 への直接リンク
Partnerships APIは主に同期的です: 通常の書き込みは1秒未満で返されます。ポーリングが必要なのは以下の場合のみです:
- HTTPクライアントがタイムアウトし、レスポンスを読み取らなかった場合。
- ネットワークの途切れが原因で接続が書き込み途中で切れた場合。
- サーバーレス/ラムダランタイムからオーケストレーションしており、再呼び出しが長時間のソケット保持よりも安価な場合。
200を受け取った場合、ポーリングしないでください; すでに答えを持っています。
すべての書き込みでオペレーションIDをキャプチャするすべての書き込みでオペレーションIDをキャプチャする への直接リンク
resp = requests.put(
f"https://accounts.rokt.com/v1/partnership/accounts/{account_id}/marketplacecontrolslists",
headers={
"Authorization": f"Bearer {token}",
"X-Platform-Parent-Account-Id": parent_account_id,
"Idempotency-Key": idem_key,
},
json=payload,
timeout=10,
)
operation_id = resp.headers.get("X-Operation-Id")
# Persist `operation_id` to durable storage BEFORE acting on resp.json().
サーバーがオペレーション行を割り当てるとすぐにX-Operation-Idヘッダーが設定されます。エラーが発生しても同様です。ボディを解析する前にログに記録して、デシリアライズのクラッシュを生き延びるようにしてください。
オペレーションIDは不透明な文字列です; 解析したり、構造を仮定したりしないでください。それらは、書き込みを発行した認証されたマネージャーアカウントのみが読み取ることができます。クロステナントの読み取り(呼び出し元の認証された親がオペレーションを所有していない場合や、X-Platform-Parent-Account-Idヘッダーがオペレーションの所有者と一致しない場合)は403を返します。オペレーションIDの所有だけでは、クロスアカウントの可視性を付与しません。すべてのポーリングにはX-Platform-Parent-Account-Idが必要です; 欠落または不一致は403を返します。
オペレーションの状態オペレーションの状態 への直接リンク
pending ──▶ in_progress ──▶ completed
╲
╲─▶ failed
| 状態 | 意味 |
|---|---|
pending | オペレーション行が作成されました; 処理はまだ開始されていません。観察されることは稀で、通常は一時的です。 |
in_progress | オペレーションがステップを実行しています。ポーリングを続けてください。 |
completed | すべてのステップが成功しました。response_bodyには元の書き込みのレスポンスペイロードが含まれています。 |
failed | 少なくとも1つのステップが失敗し、オペレーションは可能な限りロールバックされました。response_bodyにはエラーエンベロープが含まれています。 |
ポーリングの頻度ポーリングの頻度 への直接リンク
指数バックオフを使用し、上限を設けて、締切を設定します。推奨: 1sから開始し、各試行を30sまで倍増し、5 minutes後に諦めます。
- python
- node
- curl
import time, requests
def poll_operation(operation_id, token, parent_account_id, *, deadline_s=300):
delay = 1.0
start = time.monotonic()
while time.monotonic() - start < deadline_s:
resp = requests.get(
f"https://accounts.rokt.com/v1/partnership/operations/{operation_id}",
headers={
"Authorization": f"Bearer {token}",
"X-Platform-Parent-Account-Id": parent_account_id,
},
timeout=10,
)
envelope = resp.json()
op = envelope["data"]
if op["status"] in ("completed", "failed"):
return op
time.sleep(delay)
delay = min(delay * 2, 30.0)
raise TimeoutError(f"operation {operation_id} did not settle in {deadline_s}s")
async function pollOperation(operationId, token, parentAccountId, { deadlineMs = 300_000 } = {}) {
let delay = 1000;
const start = Date.now();
while (Date.now() - start < deadlineMs) {
const resp = await fetch(
`https://accounts.rokt.com/v1/partnership/operations/${operationId}`,
{
headers: {
Authorization: `Bearer ${token}`,
"X-Platform-Parent-Account-Id": parentAccountId,
},
}
);
const envelope = await resp.json();
const op = envelope.data;
if (op.status === "completed" || op.status === "failed") return op;
await new Promise((r) => setTimeout(r, delay));
delay = Math.min(delay * 2, 30_000);
}
throw new Error(`operation ${operationId} did not settle`);
}
# One-shot poll
curl https://accounts.rokt.com/v1/partnership/operations/9c7b1d2e-3a4f-4b5c-9d8e-1f2a3b4c5d6e \
-H "Authorization: Bearer $ROKT_TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT"
レスポンスの形状レスポンスの形状 への直接リンク
オペレーションの読み取りは標準のエンベロープを返します; オペレーションレコードはdataに存在します。トップレベルのstatusフィールドはHTTPステータスコードです; オペレーションライフサイクルの状態 (pending / in_progress / completed / failed) はdata.statusです。
{
"status": 200,
"error": null,
"message": "ok",
"request_id": "0e3a1b9c-1234-4abc-9def-aaaabbbbcccc",
"data": {
"operation_id": "9c7b1d2e-3a4f-4b5c-9d8e-1f2a3b4c5d6e",
"status": "completed",
"mode": "sync",
"operation_type": "configure_partnership",
"created_at": "2026-05-14T18:21:09Z",
"completed_at": "2026-05-14T18:21:11Z",
"next_retry_at": null,
"retry_count": 0,
"request_id": "0e3a1b9c-1234-4abc-9def-aaaabbbbcccc",
"response_body": {
"account_id": "<your-account-id>",
"marketplace_controls_list_id": "8c8e1c12-...",
"content_hash": "h_xyz789"
},
"error": null
}
}
completedまたはfailedオペレーションの場合、data.response_bodyは元の書き込みが返した正確なペイロードです。それを使用してワークフローを続行できます; PUTを再発行する必要はありません。
snake_caseキーは、ライブエンドポイントに一致するresponse_bodyの正規の契約です。
ウォークスルー: クライアントサイドのタイムアウトからの復旧ウォークスルー: クライアントサイドのタイムアウトからの復旧 への直接リンク
- Register a merchant; client times out
あなたの
POST /v1/accounts/register/partnership呼び出しは5秒のクライアントタイムアウトに達しました。レスポンスを読み取ることはありませんでした。 - But you logged the operation ID
あなたのHTTPクライアントはボディタイムアウトの前にレスポンスヘッダーをバッファリングしました。あなたは以下を持っています:
X-Operation-Id: 9c7b1d2e-3a4f-4b5c-9d8e-1f2a3b4c5d6e(ヘッダーも持っていない場合は、冪等性キーリプレイにフォールバックします: 同じキー、同じ書き込み。)
- Poll until terminal
curl https://accounts.rokt.com/v1/partnership/operations/9c7b1d2e-3a4f-4b5c-9d8e-1f2a3b4c5d6e \
-H "Authorization: Bearer $ROKT_TOKEN" \
-H "X-Platform-Parent-Account-Id: $PARENT"約2秒後のレスポンス:
{
"status": 200,
"error": null,
"message": "ok",
"request_id": "0e3a1b9c-...",
"data": {
"operation_id": "9c7b1d2e-...",
"status": "completed",
"operation_type": "register_partnership",
"response_body": { "account_id": "<your-account-id>" }
}
} - Use data.response_body as if it were the original response
data.response_body.account_idを元の200ボディと同様に扱います。書き込みはすでに行われており、領収書を回復しただけです。
ポーリングと冪等性キーリプレイは同じ復旧への2つのパスです。ポーリングは操作IDがある場合に推奨されます。それは検証を再実行しない安価なGETです。リプレイはクラッシュからキーだけが生き残った場合のフォールバックです。