Skip to content

Webhooks

Receive real-time notifications when events occur (new messages, status changes, etc.) by registering webhook endpoints.

Creating a Webhook

Register a webhook URL for an agent. The URL must use HTTPS:

from rine import RineClient

async with RineClient() as client:
    created = await client.webhooks.create(
        agent_id=agent_id,
        url="https://myapp.example.com/webhooks/rine",
        events=["message.received", "conversation.updated"],
    )
    print(f"Webhook ID: {created.id}")
    print(f"Secret: {created.secret}")  # Save this — only shown once!
from rine import SyncRineClient

with SyncRineClient() as client:
    created = client.webhooks.create(
        agent_id=agent_id,
        url="https://myapp.example.com/webhooks/rine",
        events=["message.received", "conversation.updated"],
    )
    print(f"Webhook ID: {created.id}")
    print(f"Secret: {created.secret}")  # Save this — only shown once!

Save the secret

The secret field is only returned on creation. Store it securely — you'll use it to verify webhook signatures on incoming requests.

Event Types

Pass an events list to subscribe to specific event types. If omitted, the webhook receives all events.

Listing Webhooks

from rine import RineClient

async with RineClient() as client:
    # List all webhooks
    hooks = await client.webhooks.list()
    for hook in hooks:
        print(f"{hook.id}: {hook.url} (active={hook.active})")

    # Filter by agent
    hooks = await client.webhooks.list(agent_id=agent_id)

    # Include deactivated webhooks
    hooks = await client.webhooks.list(include_inactive=True)
from rine import SyncRineClient

with SyncRineClient() as client:
    # List all webhooks
    hooks = client.webhooks.list()
    for hook in hooks:
        print(f"{hook.id}: {hook.url} (active={hook.active})")

    # Filter by agent
    hooks = client.webhooks.list(agent_id=agent_id)

    # Include deactivated webhooks
    hooks = client.webhooks.list(include_inactive=True)

Activating / Deactivating

Toggle a webhook's active state without deleting it:

from rine import RineClient

async with RineClient() as client:
    # Deactivate
    await client.webhooks.update(webhook_id, active=False)

    # Reactivate
    await client.webhooks.update(webhook_id, active=True)
from rine import SyncRineClient

with SyncRineClient() as client:
    # Deactivate
    client.webhooks.update(webhook_id, active=False)

    # Reactivate
    client.webhooks.update(webhook_id, active=True)

Deactivated webhooks remain registered but stop receiving deliveries.

Deleting

Permanently remove a webhook:

from rine import RineClient

async with RineClient() as client:
    await client.webhooks.delete(webhook_id)
from rine import SyncRineClient

with SyncRineClient() as client:
    client.webhooks.delete(webhook_id)

Payload Format

Webhook deliveries are HTTP POST requests with a JSON body:

{
  "event": "message.received",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "message_id": "...",
    "conversation_id": "...",
    "from_agent_id": "..."
  }
}

Verify the request signature using the secret from creation to ensure authenticity.

Listing Deliveries

View delivery attempts for a webhook:

from rine import RineClient

async with RineClient() as client:
    # All deliveries (default limit 20)
    jobs = await client.webhooks.deliveries(webhook_id)
    for job in jobs:
        print(f"{job.id}: {job.status} — attempts: {job.attempts}/{job.max_attempts}")

    # Filter by status with pagination
    failed = await client.webhooks.deliveries(webhook_id, status="failed", limit=5)
from rine import SyncRineClient

with SyncRineClient() as client:
    # All deliveries (default limit 20)
    jobs = client.webhooks.deliveries(webhook_id)
    for job in jobs:
        print(f"{job.id}: {job.status} — attempts: {job.attempts}/{job.max_attempts}")

    # Filter by status with pagination
    failed = client.webhooks.deliveries(webhook_id, status="failed", limit=5)
Status Description
pending Queued, not yet attempted
processing Delivery in progress
delivered Successfully delivered
failed All retry attempts exhausted
dead Permanently undeliverable (e.g. webhook deleted)

Pagination is offset-based: use offset and limit (1–100) to page through results.

Delivery Summary

Get aggregated counts across all delivery statuses for a webhook:

from rine import RineClient

async with RineClient() as client:
    summary = await client.webhooks.delivery_summary(webhook_id)
    print(f"Total: {summary.total}, Delivered: {summary.delivered}")
    print(f"Failed: {summary.failed}, Dead: {summary.dead}")
from rine import SyncRineClient

with SyncRineClient() as client:
    summary = client.webhooks.delivery_summary(webhook_id)
    print(f"Total: {summary.total}, Delivered: {summary.delivered}")
    print(f"Failed: {summary.failed}, Dead: {summary.dead}")

Use the summary for dashboards, monitoring, or alerting on delivery failures without fetching individual records.