Python SDK
The Python SDK provides helpers for the full pre-execution authorization flow: create a client, authorize an action, handle the three outcomes, and verify the permit before execution.
Install
pip install veritrellis
Requires Python 3.9 or later.
Quick reference
| Symbol | Purpose |
|---|---|
Client(...) | Initialize a scoped client |
client.authorize(...) | Submit an action for authorization |
client.verify_permit(permit) | Verify a permit JWT |
client.poll_permit(request_id) | Poll for a pending permit |
Create a client
import os
from veritrellis import Client
client = Client(
api_key=os.environ["VERITRELLIS_API_KEY"],
workspace_id=os.environ["VERITRELLIS_WORKSPACE_ID"],
environment="sandbox", # "sandbox" | "production"
api_url="https://api.veritrellis.ai",
)
Configuration
| Option | Type | Required | Description |
|---|---|---|---|
api_key | str | Yes | Workspace API key (vt_sandbox_… or vt_prod_…) |
workspace_id | str | Yes | Your workspace ID (ws_…) |
environment | str | Yes | "sandbox" or "production"; must match the API key |
api_url | str | No | Defaults to https://api.veritrellis.ai |
Authorize an action
Call this before any action that requires a permit. It contacts the Veritrellis API and returns one of three outcomes.
result = client.authorize(
action_type="issue_refund",
resource_ref="cus_123",
payload={
"customer_id": "cus_123",
"amount": 75,
"currency": "EUR",
"reason": "customer request",
},
)
Handling the three outcomes
if result.decision == "allowed":
# Permit is ready — verify it before executing
claims = client.verify_permit(result.permit)
# Proceed with the action using verified claims
issue_refund(claims)
elif result.decision == "pending_approval":
# Save result.request_id and poll GET /v1/permits/:request_id
save_for_polling(result.request_id)
elif result.decision == "denied":
# Policy blocked this request — do not execute
raise RuntimeError(f"Action denied: {result.reason_code}")
Receiving a permit from authorize is not sufficient. You must call verify_permit before executing the action. Permits that fail verification must not unlock execution.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
action_type | str | Yes | The canonical action type (e.g. issue_refund) |
resource_ref | str | Yes | Identifier of the resource being acted on |
payload | dict | Yes | Action-specific fields; validated against shared schemas |
actor_ref | str | No | ID of the human or agent initiating the action |
idempotency_key | str | No | Stable key for safe retries |
Response shape
| Field | Present when | Type | Description |
|---|---|---|---|
decision | Always | str | "allowed", "pending_approval", or "denied" |
request_id | Always | str | Unique request identifier |
permit | allowed only | str | Signed ES256 permit JWT |
reason_code | denied only | str | Machine-readable denial reason |
Verify a permit
Verifies a permit JWT against the workspace JWKS. The client already holds the workspace ID and issuer, so it takes a single argument. Raises if the signature, issuer, audience, or expiry check fails.
claims = client.verify_permit(result.permit)
The returned claims contains:
| Claim | Type | Description |
|---|---|---|
sub | str | Request ID this permit is bound to |
workspace_id | str | Workspace the permit was issued for |
action_type | str | Action type the permit authorizes |
resource_ref | str | Resource the permit is scoped to |
iat | int | Issued-at timestamp (Unix) |
exp | int | Expiry timestamp (Unix) |
Polling for a permit
When decision is pending_approval, poll until the request resolves:
permit = client.poll_permit(result.request_id)
# Ready — verify before executing
claims = client.verify_permit(permit)
poll_permit returns the permit once approved, and raises if the request is denied or expires.
Environment variables
| Variable | Required | Description |
|---|---|---|
VERITRELLIS_API_KEY | Yes | API key from the admin app |
VERITRELLIS_WORKSPACE_ID | Yes | Workspace ID from the admin app |
Both the API key and workspace ID are available in the admin app under Settings > API keys. The sandbox and production environments have separate keys.