Webhooks
Create webhook endpoints, configure events, verify signatures, and troubleshoot delivery.
Webhook endpoints allow you to receive real-time notifications when events occur in your oCore organization. oCore sends HTTP POST requests to your configured URLs with event details, enabling integrations with external systems, monitoring tools, chat applications, and custom automation.
Webhook Endpoints
Create and manage webhook endpoints for event notifications.
Creating a Webhook Endpoint
Navigate to Settings > Webhooks and click Create Endpoint.
Configure the endpoint:
- URL -- The HTTPS endpoint to receive webhook payloads
- Events -- Which event types to subscribe to
- Secret -- A shared secret for signature verification
- Description -- Optional description
Click Create. oCore sends a test event to verify the endpoint is reachable.
curl -X POST https://ocore.example.com/api/webhook-endpoints \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/ocore",
"events": ["deployment.completed", "deployment.failed", "backup.failed"],
"secret": "your-webhook-secret-here",
"description": "Slack notification integration"
}'ocore webhook create \
--url "https://hooks.example.com/ocore" \
--events deployment.completed,deployment.failed \
--secret your-webhook-secret-hereSupported Events
Deployment Events
| Event | Trigger |
|---|---|
deployment.triggered | Deployment started |
deployment.completed | Deployment finished successfully |
deployment.failed | Deployment failed |
deployment.rolled_back | Deployment was rolled back |
Instance Events
| Event | Trigger |
|---|---|
instance.created | New instance provisioned |
instance.started | Instance container started |
instance.stopped | Instance container stopped |
instance.deleted | Instance removed |
instance.error | Instance entered error state |
Server Events
| Event | Trigger |
|---|---|
server.created | New server added |
server.active | Server provisioning completed |
server.unreachable | Server health check failed |
server.deleted | Server removed |
Backup Events
| Event | Trigger |
|---|---|
backup.completed | Backup finished successfully |
backup.failed | Backup failed |
backup.restored | Backup restored successfully |
Team Events
| Event | Trigger |
|---|---|
member.joined | New member accepted invitation |
member.removed | Member removed from organization |
member.role_changed | Member's role was updated |
Wildcard
Subscribe to all events with * (not recommended for production -- use specific events).
Webhook Payload Format
Each webhook delivery sends a JSON payload:
{
"id": "evt_abc123",
"type": "deployment.completed",
"timestamp": "2026-02-26T18:30:00Z",
"organizationId": "ORG_UUID",
"data": {
"deploymentId": "DEPLOYMENT_UUID",
"projectId": "PROJECT_UUID",
"branch": "main",
"commitSha": "abc123def456",
"status": "completed",
"durationMs": 45000
}
}Payload Fields
| Field | Description |
|---|---|
id | Unique event ID for idempotency |
type | The event type string |
timestamp | When the event occurred (ISO 8601 UTC) |
organizationId | The organization that owns the resource |
data | Event-specific payload with relevant resource details |
HTTP Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-OCore-Signature | HMAC-SHA256 signature of the payload body |
X-OCore-Event | The event type |
X-OCore-Delivery | Unique delivery ID |
Webhook Security
Signature Verification
Every webhook delivery includes an X-OCore-Signature header containing an HMAC-SHA256 signature. Verify this signature to ensure the request came from oCore and was not tampered with.
import hmac
import hashlib
def verify_signature(payload_body: bytes, secret: str, signature: str) -> bool:
expected = hmac.new(
secret.encode('utf-8'),
payload_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)const crypto = require('crypto');
function verifySignature(payloadBody, secret, signature) {
const expected = crypto
.createHmac('sha256', secret)
.update(payloadBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(`sha256=${expected}`),
Buffer.from(signature)
);
}Always Verify Signatures
Never process webhook payloads without verifying the signature first. An attacker could send fake webhook requests to your endpoint.
Best Practices
- Use HTTPS endpoints only (plain HTTP is rejected)
- Store the webhook secret securely (environment variable, not in code)
- Use the event
idfor idempotency -- the same event may be delivered multiple times - Respond with HTTP 2xx within 10 seconds -- long processing should be done asynchronously
- Rotate webhook secrets periodically
Managing Webhook Endpoints
Listing Endpoints
curl https://ocore.example.com/api/webhook-endpoints \
-H "Authorization: Bearer $TOKEN"Updating an Endpoint
curl -X PUT https://ocore.example.com/api/webhook-endpoints/{endpointId} \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"events": ["deployment.completed", "deployment.failed", "instance.error"],
"url": "https://hooks.example.com/ocore-v2"
}'Deleting an Endpoint
curl -X DELETE https://ocore.example.com/api/webhook-endpoints/{endpointId} \
-H "Authorization: Bearer $TOKEN"Viewing Delivery History
Check recent deliveries for an endpoint to debug issues:
curl https://ocore.example.com/api/webhook-endpoints/{endpointId}/deliveries \
-H "Authorization: Bearer $TOKEN"Each delivery entry shows:
- Event type and ID
- HTTP status code returned by your endpoint
- Response time
- Request and response bodies (for debugging)
- Retry count
Troubleshooting Webhook Delivery
Endpoint not receiving events
- Verify the endpoint URL is correct and accessible from the internet
- Check that your server allows incoming HTTPS connections
- Verify the events are correctly subscribed
- Check the delivery history for error details
Deliveries returning 4xx/5xx errors
- 400 Bad Request -- Your endpoint is rejecting the payload. Check your parsing logic
- 401/403 -- Your endpoint requires authentication. Add webhook-specific auth handling
- 500 -- Your endpoint is crashing. Check server logs
- Timeout -- Your endpoint takes too long. Process asynchronously and return 200 immediately
Duplicate deliveries
- oCore retries failed deliveries (up to 3 times with exponential backoff)
- Use the
idfield for idempotency to prevent duplicate processing - Return HTTP 2xx on the first attempt to prevent retries
Signature verification failing
- Ensure you are using the raw request body (not parsed JSON) for HMAC computation
- Verify the secret matches exactly (no trailing whitespace)
- Check that you are using HMAC-SHA256 (not SHA-1 or SHA-512)
- Ensure the comparison is timing-safe to prevent timing attacks
Events not matching expected types
- Review the supported events list above
- Event types are case-sensitive
- Use the
*wildcard during development to see all events, then narrow down
Required Permissions
| Action | Permission |
|---|---|
| View webhook endpoints | view:webhook_endpoints |
| Create/update/delete endpoints | manage:webhook_endpoints |
Troubleshooting
Webhook delivery consistently failing
- Check that your endpoint responds within 10 seconds
- Ensure your HTTPS certificate is valid (self-signed certificates may be rejected)
- Verify there are no firewalls blocking incoming connections
- Test the endpoint manually with
curlto confirm it accepts POST requests
Too many webhook events
- Subscribe only to the events you need (avoid
*in production) - Implement rate limiting on your endpoint if needed
- Use a message queue on your end for buffering high-volume events