ThrustLab

client.webhook_endpoints

Register, manage, test, and replay webhook endpoints. Use this resource to let the server push notifications when an async resource finishes, so you don't have to poll. For verifying incoming deliveries on the receiving side, see webhook signature verification.

Methods

MethodEndpointReturns
client.webhook_endpoints.create(url=..., events=[...])POST /v1/webhook_endpointsNew endpoint with signing secret (one-time)
client.webhook_endpoints.list()GET /v1/webhook_endpointsCursorPager of endpoints
client.webhook_endpoints.retrieve(endpoint_id)GET /v1/webhook_endpoints/{id}Single endpoint
client.webhook_endpoints.update(endpoint_id, **fields)PATCH /v1/webhook_endpoints/{id}Updated endpoint
client.webhook_endpoints.delete(endpoint_id)DELETE /v1/webhook_endpoints/{id}None
client.webhook_endpoints.rotate_secret(endpoint_id)POST /v1/webhook_endpoints/{id}/rotate_secretEndpoint with new secret (one-time)
client.webhook_endpoints.test(endpoint_id)POST /v1/webhook_endpoints/{id}/testTest delivery
client.webhook_endpoints.list_events()GET /v1/eventsCursorPager of event occurrences (the durable event log, not a type catalog)
client.webhook_endpoints.list_deliveries(endpoint_id, status=..., event_type=..., created_at_gte=..., cursor=...)GET /v1/webhook_endpoints/{id}/deliveriesCursorPager of past delivery attempts
client.webhook_endpoints.retry_delivery(endpoint_id, delivery_id)POST .../deliveries/{did}/retryThe new delivery attempt

Register an endpoint

The signing secret is returned exactly once in the create response. Store it in your secrets manager — it's required to verify deliveries.

from thrustlab import Client

client = Client()
endpoint = client.webhook_endpoints.create(
    url="https://your-app.example.com/webhooks/thrustlab",
    events=["simulation.completed", "simulation.failed",
            "sweep.completed", "sweep.failed"],
    description="prod handler",
)
print(endpoint["id"])      # wh_2c5tQ...
print(endpoint["secret"])  # whsec_... — store immediately, can't recover

To subscribe to every event, pass events=["*"]. New event types added later will start delivering automatically.

List events

list_events() hits GET /v1/events — the durable log of every event occurrence on your account, newest first. There's no separate catalog endpoint that returns event type names and descriptions; that static list lives in the event types table in the events guide.

for evt in client.webhook_endpoints.list_events():
    print(evt["id"], evt["type"], evt["created_at"])
# evt_2c5tQ... simulation.completed 2026-04-25T18:42:11Z
# evt_2c5sK... simulation.failed    2026-04-25T18:40:02Z
# ... etc.

See the events guide for the full payload shape and filters (type, resource_id, created_at range).

Update an endpoint

client.webhook_endpoints.update(
    "wh_2c5tQ...",
    events=["simulation.completed", "sweep.completed"],
    description="prod handler — success only",
)

You can patch url, events, description, and enabled (soft pause / re-enable).

Rotate the signing secret

Rotating replaces the endpoint's signing secret immediately — the old secret stops validating signatures the instant this call returns. There's no grace window, so plan the rotation for a low-traffic period and redeploy your handler with the new value right away:

rotated = client.webhook_endpoints.rotate_secret("wh_2c5tQ...")
print(rotated["secret"])  # whsec_... — new value, store + deploy immediately

Deliveries signed with the old secret that arrive after rotation will fail your handler's signature check; the server's normal retry/backoff schedule redelivers them once you're verifying against the new secret. See signature verification for handler-side guidance.

Send a test delivery

delivery = client.webhook_endpoints.test("wh_2c5tQ...")
print(delivery["id"], delivery["status"])  # whd_... pending|succeeded|failed|permanently_failed

The test event has type: "webhook.test" and a synthetic payload; useful for smoke-testing your handler in staging.

Audit deliveries

for d in client.webhook_endpoints.list_deliveries(
    "wh_2c5tQ...",
    status="failed",
    event_type="simulation.completed",
    created_at_gte="2026-04-24T00:00:00Z",
):
    print(d["id"], d["created_at"], d["response_status_code"], d["error_message"])

status filter values: pending, succeeded, failed, permanently_failed. Also filter by event_type (the underlying event's type) and created_at_gte (ISO-8601); pass cursor= from a prior page's next_cursor to page forward.

Every dispatch also sends Webhook-Id (the source event ID) and Webhook-Attempt (1-based attempt number) headers with the POST — see the webhooks guide for the full header contract.

Replay a delivery

The server retries failed deliveries automatically on a fixed backoff schedule (immediate, +1 min, +30 min, +2 h, +24 h), permanently failing after the 5th attempt — roughly 26.5 hours after the first. To force an immediate retry (e.g. you just shipped the fix), call:

client.webhook_endpoints.retry_delivery("wh_2c5tQ...", "whd_2c5tQ...")

Only terminal deliveries (succeeded or permanently_failed) can be replayed — retrying a pending delivery returns 409 delivery_not_terminal.

Delete an endpoint

client.webhook_endpoints.delete("wh_2c5tQ...")

The server stops sending new deliveries; in-flight retries are cancelled.

See also

We use cookies and analytics tools to understand how you use ThrustLab and improve the experience. Privacy Policy

Python SDK — Webhook endpoints · ThrustLab API