Skip to main content

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:

FieldTypeRequiredDescription
webhook_urlstringYesURL to receive webhook events
eventsarrayYesEvent types to subscribe to
secretstringNoShared secret for signature verification
app_idstringConditionalRequired 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

EventDescriptionPayload
node.createdNew node createdNode object
node.updatedNode modifiedNode object + changes
node.deletedNode removedNode ID
node.embedding.updatedNode embedding changedNode ID + model info
proposal.createdNew proposalProposal object
proposal.approvedProposal approvedProposal + created nodes
proposal.rejectedProposal rejectedProposal object
share.createdNew access grantedShare object
share.revokedAccess revokedShare 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

  1. Respond quickly - Return 200 within 5 seconds
  2. Process async - Queue events for background processing
  3. Verify signatures - Always validate the signature
  4. Handle duplicates - Events may be delivered multiple times