Webhooks
Receive signed Agent, Workflow and Schedule lifecycle notifications.
On this page
Register an endpointEventsVerify signaturesHandle application functionsDelivery behaviorManagement and replayCompatibility boundaryReceive state changes without keeping an SSE connection open. Register a public HTTPS endpoint and verify each signed POST. Notifications identify resources; retrieve those resources to get current state, function calls, or final results.
Endpoint management, envelopes and signatures follow
OpenAI's webhook protocol.
The five Session lifecycle events follow
OpenAI Agents API Session webhooks.
Turn outcomes, Workflow Runs and Schedule Runs are Rebyte extensions.
Legacy Task /v1/webhooks is a separate API.
Register an endpoint
Management requires an organization key with webhooks:write; reads require
webhooks:read. Resource retrieval and function-result submission separately
require tasks:read and tasks:write. Webhook routes need no beta header;
Session routes still require OpenAI-Beta: agents=v1.
curl https://api.rebyte.ai/v1/webhook_endpoints \
-H "Authorization: Bearer $REBYTE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Application worker",
"url": "https://example.com/webhooks/rebyte",
"event_types": ["agent.session.action_required", "agent.session.idle",
"agent.session.failed", "workflow.run.action_required", "workflow.run.completed"]
}'
HTTP 200 returns object: "webhook_endpoint", id, name, url, event_types,
created_at, updated_at, signing_secret_hint, and signing_secret.
Store the secret on your server: only creation and rotation return it.
Timestamps are Unix seconds. Subscriptions cover the authenticated organization,
with at most 20 endpoints. URLs must resolve to public addresses and contain no
embedded credentials or fragment. HTTP, private destinations and redirects are
not supported.
Events
GET /v1/webhook_event_types returns the supported types.
| Event | Meaning |
|---|---|
agent.session.created | Session created. |
agent.session.in_progress | Session has active work. |
agent.session.action_required | An application function result is needed, including inside Dynamic Workflow. |
agent.session.idle | Ready for input; not a guarantee that the last Turn succeeded. |
agent.session.failed | Session entered a failed state. |
agent.session.turn.completed, .failed, .cancelled | Turn ended; data.id is the Turn ID and data.session_id its Session. |
workflow.run.created, .in_progress | Workflow Run admitted or started. |
workflow.run.action_required | Workflow Run needs an application function result. |
workflow.run.completed, .failed, .cancelled | Workflow Run ended. |
schedule.run.created, .running | Schedule Run admitted or dispatched. |
schedule.run.completed, .failed, .cancelled, .skipped | Schedule Run ended or trigger skipped; data.schedule_id identifies its Schedule. |
Webhook names use action_required; resource statuses and existing SSE event
suffixes remain requires_action. Rebyte does not emit OpenAI's
environment_connection action because self-hosted environments are unsupported.
There are no resource-deletion or token-delta webhooks.
{
"id": "evt_example", "object": "event", "created_at": 1790467200,
"type": "agent.session.action_required",
"data": { "id": "sess_example", "required_action": { "type": "function_call" } }
}
Verify signatures
Requests include webhook-id, webhook-timestamp, and webhook-signature.
Standard Webhooks HMAC-SHA256 signs id.timestamp.raw_body using the base64
bytes after the secret's whsec_ prefix. The header value is v1,BASE64_SIGNATURE.
Verify the unaltered raw body. OpenAI's SDK verifier accepts this format and,
by default, rejects timestamps more than five minutes away from the current time.
import express from "express";
import OpenAI from "openai";
const app = express();
const verifier = new OpenAI({
apiKey: process.env.REBYTE_API_KEY,
baseURL: "https://api.rebyte.ai/v1",
webhookSecret: process.env.REBYTE_WEBHOOK_SECRET,
});
app.post("/webhooks/rebyte", express.text({ type: "application/json" }),
async (req, res) => {
let event;
try {
await verifier.webhooks.verifySignature(req.body, req.headers);
event = JSON.parse(req.body);
} catch {
res.sendStatus(400);
return;
}
// Receipt-only example. A production worker must durably enqueue the
// event before acknowledging it and deduplicate by webhook-id.
console.log(event.type, event.data.id);
res.sendStatus(204);
});
app.listen(8000);
Do not put express.json() before this route. Use the generic signature verifier
when your SDK does not type Rebyte's events. The pinned openai@7.15.0 supports
verification but lacks endpoint-management methods; use HTTP for management.
Handle application functions
After verification and durable acceptance, retrieve the Session at
GET /v1/agents/sessions/{data.id} or Workflow Run at
GET /v1/workflow-agents/runs/{data.id}. If its required_actions still contains
a pending call, execute it under the appropriate application's authorization.
Deduplicate business effects by resource and call ID as well as webhook ID.
Return results through the existing Session function protocol
or Workflow Run protocol. A webhook 2xx
acknowledges delivery; it does not submit a function result. Dynamic Workflow
uses the Session route, original Turn/call IDs, and one result event per request.
Scheduled executions use these same action notifications. Retrieve a Schedule
Run at GET /v1/schedules/{data.schedule_id}/runs/{data.id} to follow its Session
or Workflow binding. No continuously connected browser is required.
Delivery behavior
Return 2xx within 10 seconds. Durably queue slow processing before acknowledging.
Non-2xx, redirects, network errors and timeouts retry with exponential backoff
for up to 2 hours from delivery creation. Waiting for processing and temporary
service unavailability count toward the same window. After it, no further automatic retries are started
and an unsuccessful delivery becomes failed. Manual redelivery starts a new
2-hour window. One receiver's failure does not block another receiver.
Execution does not wait for the receiver's response; delivery retries can outlive
the Turn or Run. They never extend function deadlines or Schedule timeouts.
Duplicates and out-of-order notifications are possible. Delivery uses at-least-once
semantics within the retry window; delivery to an unavailable receiver is not
guaranteed. Always retrieve current resource state before acting. The event body
and webhook-id stay stable across retries and manual redelivery to the same
endpoint; each attempt gets a fresh timestamp and signature. Different endpoints
receive different webhook IDs for the same event. Deduplicate by webhook-id.
Changing subscriptions affects future events. Changing a URL stops queued attempts for its old destination; manual redelivery can send an old event to the new URL. Deletion stops future attempts. Requests already in flight can still arrive. Secret rotation applies to subsequent attempts; coordinate receiver updates to allow verification of requests already in flight.
Management and replay
| Method and path | Purpose |
|---|---|
POST /v1/webhook_endpoints | Create; signing secret returned once. |
GET /v1/webhook_endpoints | List; limit (1–100) and after supported. |
GET /v1/webhook_endpoints/{id} | Retrieve without the signing secret. |
POST /v1/webhook_endpoints/{id} | Update name, url, or the complete event_types list. |
DELETE /v1/webhook_endpoints/{id} | Delete endpoint. |
POST /v1/webhook_endpoints/{id}/rotate_secret | Body {}; returns the new secret once. |
POST /v1/webhook_endpoints/{id}/test | Body {"event_type":"agent.session.created"} for a subscribed type. |
GET /v1/webhook_endpoints/{id}/events | List assigned notifications; limit and after supported. |
GET /v1/webhook_endpoints/{id}/events/{event_id}/delivery | Inspect automatic delivery status and attempt count. |
POST /v1/webhook_endpoints/{id}/events/{event_id}/redeliver | Body {} and Idempotency-Key; HTTP 202 with delivery ID. |
Tests make one signed attempt and use test_resource IDs, not real resources.
A test that receives an HTTP response returns object: "webhook_endpoint.test",
webhook_endpoint_id, event_type, success: true, status_code, event_id,
and delivery_id. Inspect status_code: a receiver's 4xx or 5xx still means
the test request completed. Network failure returns HTTP 502. Tests appear in
endpoint event history and should be ignored by production business handlers.
Delivery status is pending, delivered, failed, or skipped, with attempts,
status_code and error. Manual redelivery starts a new retry window. Repeating
the same idempotency key reuses that manual delivery while its history is
retained. Inspect it by adding
?replay_key=YOUR_KEY to the delivery-status URL. Delivery details return 404
after execution-history retention expires; immutable events remain available
for explicit redelivery.
Compatibility boundary
Rebyte subscriptions are organization-scoped; OpenAI's are project-scoped. Only the listed event types are implemented, without Responses, Batch, fine-tuning, video or safety events. Event history, delivery inspection and manual redelivery routes are Rebyte extensions.