Verification
Python server SDK
thirdfactor-sdk — create verification sessions, retrieve decisions, manage risk lists, and verify signed webhooks from Python.
The official Python SDK is a server-only client for the ThirdFactor Verify
and Partner APIs. The PyPI distribution is thirdfactor-sdk; Python code
imports it as thirdfactor.
Warning
Keep your tenant API key on the server. Never put it in browser code, a mobile application, or a public repository.
Requirements
- Python 3.9 or newer
- No runtime dependencies
- A tenant API key from Console → Settings → API keys
Installation
pip install thirdfactor-sdkCreate a session
import os
from thirdfactor import ThirdFactor
tf = ThirdFactor(
api_key=os.environ["THIRDFACTOR_API_KEY"],
base_url="https://your-tenant.thirdfactor.ai",
timeout=15,
)
session = tf.sessions.create(
vendor_data="user-42",
workflow_id="4c615aec-e173-450d-8089-30d4edc835f3",
callback_url="https://app.example.com/kyc/done",
contact_email="[email protected]",
idempotency_key="kyc-user-42",
)
print(session["id"])
print(session["url"])Persist the session id and send only its hosted url to the applicant. Use a
stable idempotency key for each logical attempt so a retry returns the original
session without charging twice.
Select a workflow
List the workflows available to the API key's tenant:
workflows = tf.request("GET", "/v3/workflows/")
for workflow in workflows:
print(workflow["id"], workflow["name"], workflow["status"])Pass one of those IDs as workflow_id when creating the session. Omit it to
use the tenant's default workflow. Existing sessions retain their frozen
workflow snapshot; workflow edits affect newly created sessions.
Retrieve a session or decision
session = tf.sessions.retrieve(session_id)
decision = tf.sessions.decision(session_id)
if decision["decision"] == "approved":
grant_access()The hosted UI result is advisory. Grant access, move money, or provision an account only after a signed webhook or this authenticated decision lookup.
Verify webhooks
Pass the untouched request bytes and the X-Webhook-Signature header before
parsing JSON:
import os
from thirdfactor import SignatureError
try:
event = tf.webhooks.construct_event(
raw_body,
signature_header,
os.environ["THIRDFACTOR_WEBHOOK_SECRET"],
)
except SignatureError:
# Reject invalid, malformed, or stale deliveries.
raiseThe verifier uses constant-time HMAC comparison and a five-minute replay window by default. See webhook signatures for the raw-body requirements.
Handle API errors
from thirdfactor import APIError
try:
session = tf.sessions.retrieve(session_id)
except APIError as error:
print(error.status) # HTTP status
print(error.body) # parsed API response
print(error.request_id) # support correlation ID, when present