Webhooks API
Receive real-time event notifications.
Setting Up Webhooks
Configure webhooks in the Developer Dashboard or via API.
Webhook URL
When events occur, OfSelf sends a POST request to your configured URL:
POST https://your-app.com/webhooks/ofself
Content-Type: application/json
X-OfSelf-Signature: sha256=abc123...
X-OfSelf-Event: node.created
X-OfSelf-Timestamp: 1705315800
Signature Verification
Verify webhook authenticity using the signature:
import hmac
import hashlib
def verify_signature(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
# In your webhook handler
is_valid = verify_signature(
request.body,
request.headers.get("X-OfSelf-Signature"),
"your-webhook-secret"
)
Endpoints
POST /webhooks/subscribe
POST Subscribe to webhook events.
curl -X POST "https://api.ofself.ai/api/v1/webhooks/subscribe" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-app.com/webhooks",
"events": ["node.created", "node.updated", "proposal.approved"],
"secret": "your-webhook-secret"
}'
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
webhook_url | string | Yes | URL to receive webhook events |
events | array | Yes | Event types to subscribe to |
secret | string | No | Shared secret for signature verification |
app_id | string | Conditional | Required if using JWT auth (not needed with API key) |
GET /webhooks/subscription
GET Get current webhook subscription.
curl -X GET "https://api.ofself.ai/api/v1/webhooks/subscription" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123"
DELETE /webhooks/subscription
DELETE Unsubscribe from webhooks.
curl -X DELETE "https://api.ofself.ai/api/v1/webhooks/subscription" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123"
Event Types
| Event | Description | Payload |
|---|---|---|
node.created | New node created | Node object |
node.updated | Node modified | Node object + changes |
node.deleted | Node removed | Node ID |
node.embedding.updated | Node embedding changed | Node ID + model info |
proposal.created | New proposal | Proposal object |
proposal.approved | Proposal approved | Proposal + created nodes |
proposal.rejected | Proposal rejected | Proposal object |
share.created | New access granted | Share object |
share.revoked | Access revoked | Share ID |
Event Payload
{
"event": "node.created",
"timestamp": "2024-01-15T10:30:00Z",
"user_id": "user_123",
"data": {
"id": "node_abc",
"title": "Team meeting",
"node_type": "EXPERIENCE"
}
}
Retry Policy
Failed deliveries are retried:
- 1st retry: 1 minute
- 2nd retry: 5 minutes
- 3rd retry: 30 minutes
- 4th retry: 2 hours
- 5th retry: 12 hours
After 5 failures, the webhook is disabled.
Best Practices
- Respond quickly - Return 200 within 5 seconds
- Process async - Queue events for background processing
- Verify signatures - Always validate the signature
- Handle duplicates - Events may be delivered multiple times