The official Python SDK for the webhook.co API — a typed client with retries, cursor pagination, idempotency, and secret redaction.
Project description
webhook.co Python SDK
The official Python SDK for the webhook.co API. A typed client with the hardening you'd otherwise hand-roll: bearer auth, bounded retries with jitter, cursor pagination, idempotency, and secret redaction — with pydantic v2 models generated from the same OpenAPI contract the API is built on.
Python 3.10+. Built on httpx.
Install
pip install webhook-co
Quickstart
import os
from webhook_co import WebhookClient
client = WebhookClient(api_key=os.environ["WEBHOOK_API_KEY"])
# Create an endpoint — the one-time ingest URL is returned once, so capture it now.
endpoint = client.endpoints.create(name="orders-prod")
print(endpoint.ingest_url)
# List events for that endpoint (auto-paginates).
for event in client.events.list(endpoint.id):
print(event.id, event.provider, event.verification_state)
The API key is a whk_-prefixed token from your dashboard. Keep it server-side — this SDK never prints
it, but it's still a credential.
Responses come back as validated pydantic models, so attributes are typed and snake_cased
(endpoint.org_id, endpoint.created_at).
Pagination
List methods return a Paginator you can iterate directly — it follows the cursor for you:
for endpoint in client.endpoints.list(name="prod"):
print(endpoint.id)
# Collect everything (careful with large result sets):
failed = client.deliveries.list(status=["failed"]).collect()
# One page at a time (e.g. to build your own UI):
page = client.endpoints.list_page(limit=50)
print(page.items, page.next_cursor)
Errors
Every failure is a WebhookError subclass, so you can narrow with except — no string matching:
from webhook_co import (
WebhookRateLimitError,
WebhookNotFoundError,
WebhookAuthenticationError,
)
try:
client.endpoints.get(endpoint_id)
except WebhookNotFoundError:
... # 404 — no such endpoint
except WebhookRateLimitError as err:
print(f"retry after {err.retry_after_s}s")
except WebhookAuthenticationError:
... # 401 — the key is invalid, expired, or revoked
Each error carries code (a stable capability-error string), status (the HTTP status), and
request_id when the server sent one.
Retries & idempotency
The client retries idempotent requests on transient failures (429/502/503/504 and network errors) with
capped exponential backoff and jitter, honouring Retry-After. It never blind-retries a
non-idempotent write — creating an endpoint, rotating a secret, or an un-keyed replay won't be sent twice
by the SDK. Replays carry an idempotency key (auto-generated if you don't pass one), so those are safe:
import uuid
client.events.replay(
event.id,
target={"kind": "destination", "destinationId": destination_id},
idempotency_key=str(uuid.uuid4()),
)
Tune the budget per client:
client = WebhookClient(api_key, max_retries=4, timeout_s=15) # defaults: 2 retries, 30s
Payloads
events.get_payload decodes the wire envelope and hands you the exact bytes (length-checked, so a
truncated body raises rather than silently short-reading):
payload = client.events.get_payload(event.id)
print(payload.content_type, len(payload.body)) # payload.body is bytes
Configuration
| Argument | Default | Notes |
|---|---|---|
api_key |
— | Required. A whk_ API key. |
base_url |
https://api.webhook.co |
Must be https (loopback http allowed for self-host / dev). |
http_client |
a new httpx.Client |
Pass your own for custom transports/proxies. |
max_retries |
2 |
Retries after the first attempt, idempotent requests only. |
timeout_s |
30 |
Per-request timeout (seconds), per httpx connect/read/write phase. |
refresh_auth |
— | Hook returning a rotated bearer on a 401 (OAuth flows). |
on_debug |
— | Redacted, single-line diagnostics — never the raw key. |
Use it as a context manager to close the underlying connection pool:
with WebhookClient(api_key) as client:
client.whoami()
API surface
endpoints (list · list_page · get · create · delete · rotate · provider_secrets add/list/revoke) ·
events (list · list_page · get · get_payload · tail · replay) · deliveries (list · list_page · get) ·
replay_destinations (create · list · delete · enable · set_ordered · rotate_signing_secret ·
list_signing_secrets) · subscriptions (create · list · delete) · audit.verify · whoami.
License
Apache-2.0
Project details
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 webhook_co-0.1.0.tar.gz.
File metadata
- Download URL: webhook_co-0.1.0.tar.gz
- Upload date:
- Size: 29.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97bc7eef4ee6e5d0ddc9956323763074d1be0db4c772937447b5562580082e72
|
|
| MD5 |
3e336e454442130f467556ca19077f84
|
|
| BLAKE2b-256 |
594fe5e3bcb871485816f2188c8a007af0319019f50389118cb7ad181764297b
|
File details
Details for the file webhook_co-0.1.0-py3-none-any.whl.
File metadata
- Download URL: webhook_co-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71a50e0463a0f4c571c8507208661b3a8856b374f4d075793c32a4146f853638
|
|
| MD5 |
5985323c2cc9418a9d425c5e5733bee4
|
|
| BLAKE2b-256 |
d901ad66c6b1ae86d08de1b7b6e1ffec53819ab312b1067155d4e1220064b7d5
|