Docs

Docs

From renting GPUs to managing datacenters, the Brokkr platform has a wide variety of useful features and integrations. Get an overview of how to use them and how to get started.

Brokkr API

Webhooks

Overview

Webhooks allow you to receive real-time HTTP POST notifications when events occur in your Brokkr organization. Instead of polling the API for changes, webhooks push data to your endpoint as events happen.

Available Events

Currently, webhooks support the following events:

  • DEVICE_LISTING_CREATED - When a new device is added to our inventory
  • DEVICE_LISTING_UPDATED - When device information or pricing is updated in our inventory
  • DEVICE_LISTING_DEPRECATED - When a device is removed from our inventory
  • DEPLOYMENT_INTERRUPTED - When a deployment is interrupted

Webhook Payload

All webhook events are delivered as HTTP POST requests with a JSON payload. The payload structure includes:

{
    // Event-specific data
    data:{
      "id": "device-uuid",
      "name": "NVIDIA RTX 4090",
      "status": "on demand",
      // ... additional fields
      }
    // Event type
    eventType: "DEVICE_LISTING_CREATED",
    // Timestamp
    timestamp: "2021-01-01T00:00:00.000Z",
  },
 

HTTP Headers

Each webhook request includes the following headers:

  • X-Webhook-Signature - HMAC-SHA256 signature for request verification
  • X-Webhook-Event - The event type (e.g., DEVICE_LISTING_CREATED)
  • X-Webhook-Delivery - Unique ID for this delivery attempt
  • X-Webhook-Timestamp - ISO 8601 timestamp of when the webhook was sent
  • User-Agent - Always set to "Brokkr-Webhooks/1.0"

Signature Verification

To ensure webhook requests are coming from Brokkr, you should verify the signature included in theX-Webhook-Signature header.

Verification Steps

  1. Extract the signature from the X-Webhook-Signature header
  2. Compute an HMAC-SHA256 hash of the raw request body using your webhook secret
  3. Compare your computed signature with the received signature

Example Implementation

Node.js / JavaScript

const crypto = require('crypto');

function verifyWebhookSignature(body, signature, secret) {
  const expectedSignature = 'sha256=' + 
    crypto.createHmac('sha256', secret)
          .update(body, 'utf8')
          .digest('hex');
  
  // Use timingSafeEqual to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express.js example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const isValid = verifyWebhookSignature(req.body, signature, process.env.WEBHOOK_SECRET);
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(req.body);
  // Process the webhook event
  console.log('Received event:', event.eventType);
  
  res.status(200).send('OK');
});

Python

import hmac
import hashlib

def verify_webhook_signature(body: bytes, signature: str, secret: str) -> bool:
    expected_signature = 'sha256=' + hmac.new(
        secret.encode('utf-8'),
        body,
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(signature, expected_signature)

# Flask example
from flask import Flask, request, abort

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-Webhook-Signature')
    body = request.get_data()
    
    if not verify_webhook_signature(body, signature, os.environ['WEBHOOK_SECRET']):
        abort(401)
    
    event = request.get_json()
    print(f"Received event: {event['eventType']}")
    
    return 'OK', 200

Go

package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "fmt"
    "io"
    "net/http"
)

func verifyWebhookSignature(body []byte, signature, secret string) bool {
    h := hmac.New(sha256.New, []byte(secret))
    h.Write(body)
    expectedSignature := "sha256=" + hex.EncodeToString(h.Sum(nil))
    
    return hmac.Equal([]byte(signature), []byte(expectedSignature))
}

func webhookHandler(w http.ResponseWriter, r *http.Request) {
    signature := r.Header.Get("X-Webhook-Signature")
    body, err := io.ReadAll(r.Body)
    if err != nil {
        http.Error(w, "Failed to read body", http.StatusBadRequest)
        return
    }
    
    if !verifyWebhookSignature(body, signature, os.Getenv("WEBHOOK_SECRET")) {
        http.Error(w, "Invalid signature", http.StatusUnauthorized)
        return
    }
    
    // Process the webhook
    fmt.Println("Webhook verified and received")
    w.WriteHeader(http.StatusOK)
}

Retry Logic

Brokkr implements automatic retry logic for failed webhook deliveries:

  • Webhooks are retried up to 5 times with linear backoff
  • Retry delays: 1, 2, 3, 4, and 5 minutes after each failure
  • A webhook is considered successful if it returns a 2xx HTTP status code
  • After 10 consecutive failures across multiple events, the webhook will be automatically disabled

Best Practices

  • Always verify signatures - This ensures requests are authentic and haven't been tampered with
  • Respond quickly - Return a 2xx response as soon as possible (within 10 seconds)
  • Process asynchronously - Queue events for processing rather than handling them synchronously
  • Handle duplicates - Use the delivery ID to ensure idempotent processing
  • Store the raw payload - Keep the original event data for debugging and reprocessing
  • Monitor failures - Set up alerts for webhook failures in your system

Testing Webhooks

To test your webhook implementation:

  1. Use a tool like webhook.site to create a temporary endpoint
  2. Create a webhook pointing to your test endpoint
  3. Trigger events in your Brokkr account (e.g., update device pricing)
  4. Verify the payload structure and test your signature verification

Webhook Management

You can manage webhooks through the Brokkr dashboard or API:

  • Create webhooks with specific event subscriptions
  • View delivery history and debug failed deliveries
  • Manually retry successful or failed deliveries
  • Update endpoint URLs and event subscriptions
  • Regenerate webhook secrets if compromised
  • Temporarily disable webhooks during maintenance

Security Considerations

  • Always use HTTPS endpoints to prevent man-in-the-middle attacks
  • Store webhook secrets securely (use environment variables, not hardcoded values)
  • Implement rate limiting on your webhook endpoint
  • Log webhook requests for audit purposes
  • Rotate webhook secrets periodically
  • Validate the webhook payload structure and data types