Python client for Postcept, Proof-of-Completion for AI agents. Verify high-risk agent actions against the system of record and get a signed completion receipt.
Project description
Postcept Python SDK
Submit Proof-of-Completion verifications for your AI agents' high-risk actions.
pip install postcept
Usage
from postcept import Postcept
pc = Postcept(api_key="pcpt_sk_...") # create a key in the dashboard
# After your agent issues a refund, prove it actually completed:
result = pc.verify_refund(
operation_id="refund_8F31", # stable across retries
agent_id="SupportAgent-04",
refund_id="re_4md82k",
amount_cents=12000,
currency="usd",
customer="mara.ellis@example.com",
idempotency_key="refund_8F31", # safe to retry
)
print(result["result"]) # "verified" | "incomplete" | "duplicated" | "mismatched" | "policy_failed"
print(result["lifecycle"]) # "pending_finality" | "finalized" | "unobserved" | "reversed" | ...
print(result["safe_to_claim_complete"]) # True only when verified and the provider state is terminal
print(result["claim_reason"]) # why it isn't safe, e.g. "pending_finality"
print(result["receipt"]["id"]) # signed completion receipt
Act on safe_to_claim_complete, not on the raw result. When it is False,
claim_reason tells you what to say. pending_finality means the provider is
still settling, so tell the customer "processing" and re-check later. Anything
else means the work is not done, so surface the gap and recover.
Cancellations work the same way:
pc.verify_cancellation(
operation_id="cancel_2240",
agent_id="SupportAgent-04",
subscription_id="sub_9Kd21",
customer="mara.ellis@example.com",
)
Read your Verified Completion Rate:
pc.verified_completion_rate() # {"claimed": 1240, "verified": 1167, "verified_completion_rate": 0.9411, ...}
Notes
- Auth: pass an organization API key (
pcpt_sk_...). All data is scoped to that org. - Idempotency: pass
idempotency_keyso retried submissions return the original verification instead of creating a duplicate. - Errors: non-2xx responses raise
PostceptError(.status_code,.detail). - Base URL: defaults to
https://api.postcept.com. Override withPostcept(api_key=..., base_url=...)for staging. - Use as a context manager (
with Postcept(...) as pc:) to close the HTTP client.
Verifying lifecycle webhooks
Postcept can push signed lifecycle events (a verification created, a previously
verified refund later reversed) to an endpoint you register in the dashboard or
via POST /v1/webhook-endpoints. Verify every delivery against the raw request
body before acting on it:
from postcept import verify_webhook_signature
# In your handler, BEFORE parsing the JSON:
ok = verify_webhook_signature(
payload=raw_body_bytes,
header=request.headers["Postcept-Signature"],
secret=os.environ["POSTCEPT_WEBHOOK_SECRET"],
)
Stale timestamps are rejected (replay protection, 5-minute default). Delivery is
at-least-once and unordered: de-duplicate by the Postcept-Event-Id header.
During a secret rotation the header carries a signature for both the new and the
previous secret, so you can switch without dropping deliveries.
Guarded actions
Run your action in your own code, then verify it, and get a customer-safe status:
result = pc.guard_refund(
lambda: stripe.Refund.create(charge="ch_1P09x", amount=12000), # YOUR code
operation_id="refund_8F31", agent_id="SupportAgent-04",
refund_id="re_4md82k", amount_cents=12000, customer="mara.ellis@example.com",
)
result.action # whatever your function returned
result.safe_to_claim_complete # True only when verified AND final
result.status # "completed" | "processing" | "failed" | "unverified" | "unreachable"
result.customer_message # a non-false sentence for that status
Postcept never runs your action or holds write authority. guard_refund never
raises for a non-verified or unreachable outcome (they're in the result). A raise
from your own action propagates. A pending refund yields status="processing",
never "done".
OpenTelemetry
Export Postcept outcomes to your existing observability tool. Attach the
standard postcept.* attributes to your own span (no OTel dependency forced):
from opentelemetry import trace
from postcept import postcept_span_attributes
result = pc.verify_refund(...)
trace.get_current_span().set_attributes(postcept_span_attributes(result))
Works with any OTel-compatible backend (LangSmith, Phoenix, Datadog, Honeycomb, plain OTLP).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file postcept-0.3.0.tar.gz.
File metadata
- Download URL: postcept-0.3.0.tar.gz
- Upload date:
- Size: 22.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3c997636342cf036638335b88feaa392bfebe2f798a225e7b98d7c4abded3dd
|
|
| MD5 |
b23a52d51448a467a7291a4d6081df0c
|
|
| BLAKE2b-256 |
e81ce6907c7450b59e7b923227d92b8ae03976124ecba8a16b3305afa62596ca
|
File details
Details for the file postcept-0.3.0-py3-none-any.whl.
File metadata
- Download URL: postcept-0.3.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0361199e2a3313a03b1767ab1766df21e9a38693ff7bc8297f4fd38a73aa73df
|
|
| MD5 |
2b40cff6c96106f6968cfea6b9378a7f
|
|
| BLAKE2b-256 |
5fa27b3cf66271b1a58bfc67017af41e7c54ab6478b331105cb561e27174e3d8
|