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 /third-party/webhooks
POST Subscribe to webhook events.
curl -X POST "https://api.ofself.ai/api/v1/third-party/webhooks" \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks",
"events": ["node.created", "proposal.approved"],
"secret": "your-webhook-secret"
}'
GET /third-party/webhooks
GET Get current webhook configuration.
DELETE /third-party/webhooks
DELETE Unsubscribe from webhooks.
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 |
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": "New Note",
"node_type": "note"
}
}
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