Webhooks

Webhooks allow you to receive real-time notifications when events occur in your Outstand account. Instead of polling our API for updates, webhooks push data to your endpoint as soon as something happens.

Overview

When you configure a webhook endpoint, Outstand will send an HTTP POST request to your specified URL whenever a subscribed event occurs. This enables you to:

  • Get instant notifications when posts are published successfully
  • Be alerted immediately when publishing errors occur
  • Build automated workflows based on Outstand events
  • Integrate with your existing systems and dashboards

Setting Up Webhooks

Creating a Webhook Endpoint

  1. Navigate to Settings in the Outstand web application
  2. Click on Webhooks in the sidebar
  3. Click the Add Webhook button
  4. Fill in the webhook configuration form:
FieldDescriptionRequired
NameA friendly name to identify this webhook (e.g., "Production Notifications")Yes
Endpoint URLThe HTTPS URL where Outstand will send webhook payloadsYes
Signing SecretA secret key used to sign payloads with HMAC-SHA256No
Custom HeadersAdditional HTTP headers to include in webhook requestsNo
EventsWhich events should trigger this webhookYes
  1. Select the events you want to subscribe to
  2. Click Create to save the webhook

Managing Webhooks

From the Webhooks settings page, you can:

  • Enable/Disable a webhook using the toggle switch
  • Edit a webhook's configuration by clicking the Edit button
  • Test a webhook to verify your endpoint is working
  • Delete a webhook when it's no longer needed

Available Events

EventDescription
post.publishedTriggered when a post is successfully published to at least one social account
post.errorTriggered when a post fails to publish to all targeted social accounts

Webhook Payload Format

All webhook payloads are sent as JSON with the following structure:

Headers

Content-Type: application/json
User-Agent: Outstand-Webhooks/1.0
X-Outstand-Signature: sha256=<signature> (if signing secret is configured)

Plus any custom headers you configured.

post.published Event

Sent when a post is successfully published to at least one social account.

{
  "event": "post.published",
  "timestamp": "2024-12-29T10:30:00.000Z",
  "data": {
    "postId": "9dyJS",
    "orgId": "org_abc123",
    "socialAccounts": [
      {
        "network": "threads",
        "username": "@myaccount",
        "platformPostId": "12345678901234567"
      },
      {
        "network": "linkedin",
        "username": "John Doe",
        "platformPostId": "urn:li:share:7654321"
      }
    ]
  }
}

post.error Event

Sent when a post fails to publish to all targeted social accounts.

{
  "event": "post.error",
  "timestamp": "2024-12-29T10:30:00.000Z",
  "data": {
    "postId": "9dyJS",
    "orgId": "org_abc123",
    "socialAccounts": [
      {
        "network": "threads",
        "username": "@myaccount",
        "error": "Rate limit exceeded. Please try again later."
      },
      {
        "network": "instagram",
        "username": "@myinsta",
        "error": "Access token has expired"
      }
    ]
  }
}

Verifying Webhook Signatures

If you configure a signing secret, Outstand will include an X-Outstand-Signature header with each request. This allows you to verify that the webhook came from Outstand and wasn't tampered with.

The signature is computed as an HMAC-SHA256 hash of the raw request body using your signing secret:

// Node.js example
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expectedSignature = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-outstand-signature'];
  const isValid = verifySignature(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook...
  res.status(200).send('OK');
});
# Python example
import hmac
import hashlib

def verify_signature(payload: str, signature: str, secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        secret.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

# In your webhook handler
@app.route('/webhook', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-Outstand-Signature')
    is_valid = verify_signature(
        request.get_data(as_text=True),
        signature,
        os.environ['WEBHOOK_SECRET']
    )
    
    if not is_valid:
        return 'Invalid signature', 401
    
    # Process the webhook...
    return 'OK', 200

Delivery & Retries

Outstand provides a scalable and reliable delivery mechanism to deliver webhooks, which provides:

  • Automatic retries: Failed deliveries are retried up to 5 times with exponential backoff
  • Retry intervals: Starting at 10 seconds, increasing up to 5 minutes between attempts
  • Timeout: Each delivery attempt has a 30-second timeout

Response Requirements

Your endpoint should:

  • Return a 2xx status code (200-299) to acknowledge receipt
  • Respond within 30 seconds
  • Be idempotent (handle duplicate deliveries gracefully)

If your endpoint returns a 4xx or 5xx status code, or times out, the delivery will be retried.

Best Practices

  1. Always verify signatures if you've configured a signing secret
  2. Respond quickly - do heavy processing asynchronously after acknowledging the webhook
  3. Handle duplicates - use the postId and timestamp to deduplicate if needed
  4. Use HTTPS - webhook endpoints must use HTTPS for security
  5. Test your endpoint - use the Test button in the UI before going live
  6. Monitor failures - set up alerting for failed webhook deliveries on your end

Testing Webhooks

You can test your webhook configuration directly from the Outstand UI:

  1. Go to SettingsWebhooks
  2. Find the webhook you want to test
  3. Click the Test button

This will send a test payload to your endpoint:

{
  "event": "test",
  "timestamp": "2024-12-29T10:30:00.000Z",
  "data": {
    "message": "This is a test webhook from Outstand",
    "endpointId": 123
  }
}

The test result will show you the HTTP status code returned by your endpoint.