Configure and manage webhooks for real-time event notifications.
Method Endpoint Description GET/webhooksList webhook endpoints POST/webhooksCreate a webhook GET/webhooks/:idGet webhook details PATCH/webhooks/:idUpdate a webhook DELETE/webhooks/:idDelete a webhook GET/webhooks/:id/deliveriesList delivery attempts POST/webhooks/:id/testSend test event
1 {
2 "id" : "wh_abc123" ,
3 "url" : "https://example.com/webhooks/bootspring" ,
4 "events" : [ "project.created" , "agent.invoked" ] ,
5 "status" : "active" ,
6 "secret" : "whsec_xxx..." ,
7 "metadata" : {
8 "environment" : "production"
9 } ,
10 "stats" : {
11 "deliveriesTotal" : 156 ,
12 "deliveriesSucceeded" : 152 ,
13 "deliveriesFailed" : 4 ,
14 "lastDeliveryAt" : "2024-01-15T10:30:00Z"
15 } ,
16 "createdAt" : "2024-01-01T00:00:00Z"
17 }
Event Description project.createdNew project created project.updatedProject settings updated project.deletedProject deleted
Event Description agent.invokedAgent was invoked agent.completedAgent completed task agent.failedAgent invocation failed
Event Description skill.appliedSkill pattern applied skill.failedSkill application failed
Event Description usage.threshold_reachedUsage threshold reached usage.limit_exceededUsage limit exceeded
Event Description subscription.createdSubscription started subscription.updatedSubscription changed subscription.canceledSubscription canceled invoice.paidInvoice payment succeeded invoice.payment_failedInvoice payment failed
curl https://api.bootspring.dev/v1/webhooks \
-H "Authorization: Bearer bs_xxx"
1 {
2 "data" : [
3 {
4 "id" : "wh_abc123" ,
5 "url" : "https://example.com/webhooks/bootspring" ,
6 "events" : [ "project.created" , "agent.invoked" ] ,
7 "status" : "active" ,
8 "createdAt" : "2024-01-01T00:00:00Z"
9 }
10 ]
11 }
Field Type Required Description urlstring Yes HTTPS endpoint URL eventsarray Yes Events to subscribe to metadataobject No Custom metadata
1 curl -X POST https://api.bootspring.dev/v1/webhooks \
2 -H "Authorization: Bearer bs_xxx" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "url": "https://example.com/webhooks/bootspring",
6 "events": ["project.created", "agent.invoked", "usage.threshold_reached"],
7 "metadata": {
8 "environment": "production"
9 }
10 }'
1 {
2 "data" : {
3 "id" : "wh_def456" ,
4 "url" : "https://example.com/webhooks/bootspring" ,
5 "events" : [ "project.created" , "agent.invoked" , "usage.threshold_reached" ] ,
6 "status" : "active" ,
7 "secret" : "whsec_abc123xyz..." ,
8 "metadata" : {
9 "environment" : "production"
10 } ,
11 "createdAt" : "2024-01-15T12:00:00Z"
12 }
13 }
Important : The secret is only shown once. Store it securely for signature verification.
Field Type Description urlstring Endpoint URL eventsarray Events to subscribe to statusstring active or disabledmetadataobject Custom metadata
1 curl -X PATCH https://api.bootspring.dev/v1/webhooks/wh_abc123 \
2 -H "Authorization: Bearer bs_xxx" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "events": ["project.created", "project.updated"],
6 "status": "active"
7 }'
curl -X DELETE https://api.bootspring.dev/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer bs_xxx"
GET /webhooks/:id/deliveries
Parameter Type Description statusstring Filter: success, failed, pending limitinteger Number of deliveries (default: 20)
1 {
2 "data" : [
3 {
4 "id" : "del_xyz789" ,
5 "event" : "project.created" ,
6 "status" : "success" ,
7 "statusCode" : 200 ,
8 "duration" : 145 ,
9 "attemptCount" : 1 ,
10 "request" : {
11 "headers" : { "Content-Type" : "application/json" } ,
12 "body" : "{...}"
13 } ,
14 "response" : {
15 "statusCode" : 200 ,
16 "body" : "OK"
17 } ,
18 "createdAt" : "2024-01-15T10:30:00Z"
19 }
20 ]
21 }
Field Type Required Description eventstring Yes Event type to simulate
1 curl -X POST https://api.bootspring.dev/v1/webhooks/wh_abc123/test \
2 -H "Authorization: Bearer bs_xxx" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "event": "project.created"
6 }'
POST /your-webhook-endpoint
1 {
2 "id" : "evt_abc123" ,
3 "type" : "project.created" ,
4 "timestamp" : "2024-01-15T10:30:00Z" ,
5 "data" : {
6 "project" : {
7 "id" : "proj_xyz" ,
8 "name" : "New Project" ,
9 "createdAt" : "2024-01-15T10:30:00Z"
10 }
11 }
12 }
Verify webhook signatures to ensure requests are from Bootspring.
1 import crypto from 'crypto' ;
2
3 function verifyWebhookSignature (
4 payload : string ,
5 signature : string ,
6 secret : string
7 ) : boolean {
8 const expectedSignature = crypto
9 . createHmac ( 'sha256' , secret )
10 . update ( payload )
11 . digest ( 'hex' ) ;
12
13 const expected = ` sha256= ${ expectedSignature } ` ;
14
15 return crypto . timingSafeEqual (
16 Buffer . from ( signature ) ,
17 Buffer . from ( expected )
18 ) ;
19 }
20
21 // Express middleware
22 app . post ( '/webhooks/bootspring' , ( req , res ) => {
23 const signature = req . headers [ 'x-bootspring-signature' ] ;
24 const payload = JSON . stringify ( req . body ) ;
25
26 if ( ! verifyWebhookSignature ( payload , signature , process . env . WEBHOOK_SECRET ) ) {
27 return res . status ( 401 ) . send ( 'Invalid signature' ) ;
28 }
29
30 // Process webhook
31 const event = req . body ;
32 console . log ( ` Received ${ event . type } : ` , event . data ) ;
33
34 res . status ( 200 ) . send ( 'OK' ) ;
35 } ) ;
1 import hmac
2 import hashlib
3
4 def verify_webhook_signature ( payload : str , signature : str , secret : str ) - > bool :
5 expected = 'sha256=' + hmac . new (
6 secret . encode ( ) ,
7 payload . encode ( ) ,
8 hashlib . sha256
9 ) . hexdigest ( )
10
11 return hmac . compare_digest ( signature , expected )
Failed deliveries are retried with exponential backoff:
Attempt Delay 1 Immediate 2 1 minute 3 5 minutes 4 30 minutes 5 2 hours 6 12 hours 7 24 hours
After 7 failed attempts, the delivery is marked as failed.
Return a 2xx response within 30 seconds:
1 app . post ( '/webhooks' , async ( req , res ) => {
2 // Acknowledge immediately
3 res . status ( 200 ) . send ( 'OK' ) ;
4
5 // Process asynchronously
6 processWebhook ( req . body ) . catch ( console . error ) ;
7 } ) ;
Webhooks may be delivered multiple times. Use the event id for idempotency:
1 const processedEvents = new Set ( ) ;
2
3 async function handleWebhook ( event ) {
4 if ( processedEvents . has ( event . id ) ) {
5 return ; // Already processed
6 }
7
8 processedEvents . add ( event . id ) ;
9 // Process event...
10 }
Always verify signatures in production.
Webhook endpoints must use HTTPS.
Plan Webhooks Events/Hour Free 1 100 Pro 5 1,000 Team 20 10,000 Enterprise Unlimited Unlimited
Code Description webhook_not_foundWebhook doesn't exist webhook_limit_exceededMaximum webhooks reached invalid_urlURL is not valid HTTPS invalid_eventUnknown event type