Orceum webhooks let your app push events into the assistant’s context. Instead of waiting to be called, your app can proactively notify users: “Your export is ready”, “New ticket assigned to you”, “Payment failed.” This is distinct from lifecycle webhooks, which are Orceum calling you to report installation events.

Setup

To enable events, navigate to the Webhooks section of your app in the Orceum Developer Studio. Toggle Events Enabled on. Orceum will generate a Webhook Secret (prefixed with whs_), which you can view in the dashboard. You will use this secret to sign the events you push to Orceum.
Your Webhook Secret (the whs_* token) is generated by Orceum and is used to sign the proactive events you push to Orceum. This is separate from the orc_* secret used to verify lifecycle webhooks Orceum sends to you.

Pushing an Event

Send a POST request to the Orceum events endpoint with your app’s app_id and user’s installation_id:
curl -X POST https://api.orceum.com/v1/apps/{app_id}/events \
  -H "Content-Type: application/json" \
  -H "X-Orceum-Webhook-Secret: whs_your_secret" \
  -H "X-Hub-Signature-256: sha256=<hmac_signature>" \
  -H "X-Timestamp: 2024-01-15T12:00:00Z" \
  -d '{
    "installation_id": "inst_abc123",
    "event_type": "task.completed",
    "event_data": {
      "task_id": "task_789",
      "title": "Send Q4 report",
      "completed_at": "2024-01-15T12:00:00Z"
    },
    "timestamp": "2024-01-15T12:00:00Z",
    "priority": "normal",
    "metadata": {
      "source": "todo-api",
      "user_id": "user_123"
    }
  }'

Event Fields

installation_id
string
required
The Orceum installation ID for the user this event is for. Identifies which user’s conversation to target.
event_type
string
required
A dot-separated descriptor of what happened. Convention: noun.verb — e.g. task.completed, payment.failed, report.ready.
event_data
object
required
Payload containing all relevant context about the event. Be specific — the assistant uses this to compose the message to the user.
timestamp
string
required
ISO 8601 UTC timestamp of when the event occurred.
priority
string
default:"normal"
Urgency level. One of: low, normal, high, critical
  • critical — triggers immediate notification regardless of digest settings
  • high — prioritized for delivery
  • normal / low — subject to digest and quiet-hour settings
metadata
object
Arbitrary key-value pairs for your own tracking. Not shown to users but available for debugging.

Signing Requests (HMAC)

Every event you push must be signed so Orceum can verify it came from you. Algorithm: HMAC-SHA256 over the compact JSON body using your whs_* secret. The signature is the raw hex digest — no prefix.
import hmac
import hashlib
import json

def sign_payload(payload: dict, secret: str) -> str:
    """Sign a webhook payload with HMAC-SHA256."""
    # IMPORTANT: compact JSON, sorted keys, no extra spaces
    body = json.dumps(payload, separators=(",", ":"), sort_keys=True)
    signature = hmac.new(
        secret.encode("utf-8"),
        body.encode("utf-8"),
        hashlib.sha256
    ).hexdigest()
    return signature  # Raw hex — no 'sha256=' prefix in the value itself

# Usage:
payload = {
    "installation_id": "inst_abc123",
    "event_type": "task.completed",
    "event_data": {"task_id": "task_789"},
    "timestamp": "2024-01-15T12:00:00Z",
    "priority": "normal"
}
sig = sign_payload(payload, "whs_your_secret")

headers = {
    "Content-Type": "application/json",
    "X-Orceum-Webhook-Secret": "whs_your_secret",
    "X-Hub-Signature-256": f"sha256={sig}",
    "X-Timestamp": payload["timestamp"]
}
The HMAC is computed over the compact JSON representation (no spaces, sorted keys). If you send pretty-printed JSON, the signature will not match.

Response

A successful push returns:
{
  "event_id": "evt_abc123",
  "status": "QUEUED",
  "action_taken": "CONVERSATION_STARTED"
}

action_taken Values

ValueMeaning
NOTIFIEDUser was notified (push notification sent)
CONVERSATION_STARTEDA new conversation was started with the event context
QUEUEDEvent queued for digest delivery
IGNOREDEvent was filtered out (below priority threshold, quiet hours, or bouncer decision)

Event Delivery

When your app pushes an event, Orceum dynamically decides whether and how to present it to the user. This decision is based on the user’s personal notification preferences, their current context, and what the assistant determines is most relevant and necessary at that moment.

Verifying the Endpoint

Check that your webhook integration is working:
curl https://api.orceum.com/v1/apps/{app_id}/events/verify \
  -H "Authorization: Bearer YOUR_ORCEUM_TOKEN"
{
  "reachable": true,
  "last_event_at": "2024-01-15T11:55:00Z",
  "events_enabled": true
}

Two Secrets — Which Is Which?

A common source of confusion:
SecretPrefixWho Generates ItUsed For
webhook_secretwhs_*Orceum (visible in the dashboard)Signing proactive events you push to Orceum
orceum_webhook_secretorc_*Orceum (shown once on creation)Verifying lifecycle webhooks Orceum sends to your installation_webhook_url