Outbound Webhooks
このコンテンツはまだ日本語訳がありません。
Outbound webhooks send HTTP POST notifications to your server when task events occur. They fire for all tasks in your organization, whether created via API, UI, or any other channel.
Events
Section titled “Events”| Event | Fires when |
|---|---|
task.created | A new task is created |
task.running | The agent starts executing |
task.completed | Task finishes successfully |
task.failed | Task fails |
task.canceled | Task is canceled by user |
Create Webhook
Section titled “Create Webhook”POST /v1/webhooks| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS endpoint URL |
events | string[] | Yes | Events to subscribe to |
description | string | No | Human-readable label (max 500 chars) |
secret | string | No | Pre-shared secret (max 500 chars). When set, included as X-Webhook-Secret header in every delivery. |
# Webhook without secretcurl -X POST https://api.rebyte.ai/v1/webhooks \ -H "API_KEY: rbk_xxx" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-server.com/webhook", "events": ["task.completed", "task.failed"] }'
# Webhook with pre-shared secretcurl -X POST https://api.rebyte.ai/v1/webhooks \ -H "API_KEY: rbk_xxx" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-server.com/webhook", "events": ["task.completed", "task.failed"], "secret": "my-shared-secret-value" }'Response (201):
{ "id": "880e8400-...", "url": "https://your-server.com/webhook", "events": ["task.completed", "task.failed"], "description": null, "hasSecret": true, "isActive": true, "createdAt": "2026-01-28T12:00:00.000Z", "lastTriggeredAt": null, "failureCount": 0}Behavior notes:
- Duplicate URLs: registering the same URL twice returns the existing webhook (idempotent)
- Limit: maximum 3 webhooks per organization. The 4th returns
limit_exceeded. - Secret storage: the secret value is never returned in any response. Only
hasSecret: true/falseis exposed.
List Webhooks
Section titled “List Webhooks”GET /v1/webhooksReturns all webhooks for your organization with status info (lastTriggeredAt, failureCount, isActive). Secrets are never exposed.
Get Webhook
Section titled “Get Webhook”GET /v1/webhooks/:idDelete Webhook
Section titled “Delete Webhook”DELETE /v1/webhooks/:idReturns 204 No Content. Deleted webhooks immediately stop receiving deliveries.
Delivery
Section titled “Delivery”When a task event matches a webhook’s subscribed events, Rebyte sends an HTTP POST to the webhook URL.
Payload:
{ "event": "task.completed", "taskId": "550e8400-e29b-41d4-a716-446655440000", "timestamp": 1706443200, "data": { "status": "succeeded", "taskUrl": "https://app.rebyte.ai/run/550e8400-...", "result": "Created CSV file with 10 Hacker News posts..." }}status— prompt status:pending(task.created),running(task.running),succeeded(task.completed),failed(task.failed),canceled(task.canceled)taskUrl— direct link to the task in the Rebyte UI (always present)result— final AI output text (present on terminal events:task.completed,task.failed,task.canceled; absent ontask.createdandtask.running)
Call GET /v1/tasks/:id for full task details including prompt history.
Delivery headers:
| Header | Always present | Description |
|---|---|---|
Content-Type | Yes | application/json |
X-Webhook-Signature | Yes | Base64-encoded RSA-SHA256 signature |
X-Webhook-Timestamp | Yes | Unix timestamp (seconds) |
X-Webhook-Secret | Only if secret configured | The pre-shared secret value you set on creation |
Timeout: deliveries time out after 10 seconds.
Failure handling:
- Delivery is fire-and-forget — no automatic retries on failure
- Non-2xx responses increment
failureCount - After 10 consecutive failures, the webhook is automatically disabled (
isActive: false) - Successful deliveries reset
failureCountto 0
Signature Verification
Section titled “Signature Verification”Every delivery is signed with your organization’s RSA-2048 key pair, regardless of whether a pre-shared secret is configured.
How it works:
- Rebyte concatenates
{timestamp}.{body}(e.g.,1706443200.{"event":"task.completed",...}) - Signs the string with RSA-SHA256 using your org’s private key
- Sends the base64-encoded signature in
X-Webhook-Signature
Get your public key: retrieve it from the API Playground.
Verification example (Node.js):
const crypto = require('crypto');
function verifyWebhook(rawBody, timestamp, signature, publicKey) { const payload = `${timestamp}.${rawBody}`; const verifier = crypto.createVerify('RSA-SHA256'); verifier.update(payload); return verifier.verify(publicKey, signature, 'base64');}
// In your webhook handler:app.post('/webhook', (req, res) => { const rawBody = req.body; // must be raw string, not parsed JSON const timestamp = req.headers['x-webhook-timestamp']; const signature = req.headers['x-webhook-signature'];
if (!verifyWebhook(rawBody, timestamp, signature, PUBLIC_KEY)) { return res.status(401).send('Invalid signature'); }
const event = JSON.parse(rawBody); console.log(`Task ${event.taskId}: ${event.event}`); res.status(200).send('OK');});Verification example (Python):
from cryptography.hazmat.primitives import hashes, serializationfrom cryptography.hazmat.primitives.asymmetric import paddingimport base64
def verify_webhook(raw_body: str, timestamp: str, signature: str, public_key_pem: str) -> bool: public_key = serialization.load_pem_public_key(public_key_pem.encode()) payload = f"{timestamp}.{raw_body}".encode() try: public_key.verify( base64.b64decode(signature), payload, padding.PKCS1v15(), hashes.SHA256() ) return True except Exception: return FalseTwo-Layer Security
Section titled “Two-Layer Security”Webhooks support two independent verification methods that can be used together:
| Method | Header | How it works | Use case |
|---|---|---|---|
| RSA signature | X-Webhook-Signature | Cryptographic proof the payload came from Rebyte | Tamper-proof verification |
| Pre-shared secret | X-Webhook-Secret | Static string you set on creation, echoed back in every delivery | Simple shared-secret check |
RSA signatures are always present. The pre-shared secret is optional — set it when creating the webhook if you want a simpler verification path.