Python SDK
Server helpers in sdk/python/playflow.py, package retentionplay-sdk 0.3.0, Python 3.9+. Install the repository package or add sdk/python to PYTHONPATH. Only the standard library is needed at runtime. Registry publication is separate.
Issue a session token
import os
from playflow import issue_session_token
result = issue_session_token(
api_base=os.environ["API_BASE"],
api_key=os.environ["SERVER_API_KEY"],
project_id=os.environ["PROJECT_ID"],
external_user_id=os.environ["EXTERNAL_USER_ID"],
)
token = result["session_token"]
# Pass token to your renderer; never log it.The server key needs session:issue; the helper calls the issuance endpoint using Bearer authorization. HTTP errors raise. Local session signing is unsupported.
Read progress
Run in the same process after issuance:
import json
import urllib.request
request = urllib.request.Request(
os.environ["API_BASE"].rstrip("/") + "/v1/progress/state",
headers={"Authorization": "Bearer " + token, "Origin": os.environ["SITE_ORIGIN"]},
)
with urllib.request.urlopen(request) as response:
state = json.load(response)No token is placed in the URL. HTTP errors raise before a result is returned. SITE_ORIGIN must be an exact site origin permitted by the project. Server progress reads still require it when the allowlist is nonempty.
Verify a webhook
Framework-neutral function: your HTTP adapter supplies the raw UTF-8 body and headers, then converts the returned status to a response. Persist successful fulfilment by idempotency_key before acknowledging it.
import json
import os
from playflow import verify_webhook
def receive_webhook(raw, headers):
sig = headers.get("X-RetentionPlay-Signature") or headers.get("X-PlayFlow-Signature", "")
if not verify_webhook(raw, sig, os.environ["PROJECT_WEBHOOK_SECRET"]):
return 400
event = json.loads(raw)
# Fulfil event['idempotency_key'] once in your database.
return 204The project secret comes from admin reveal. The verifier accepts versioned and legacy headers, checks the default 300-second clock window and compares HMAC-SHA256 in constant time. Preserve the exact body; webhook contract.