Skip to main content
WEBHOOK
balance_check.run.completed
{
  "event_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "type": "BALANCE_BATCH_COMPLETED",
  "batch_id": "5d3c6bbb-fc1a-46a4-93da-1ce4a54b0d83"
}

Balance Check Run Completed Webhook

Fires when a balance check run completes. A notification will be sent to the webhook_url specified in the /v1/balance_requests endpoint.
Important Considerations:
  • Webhook delivery is not guaranteed
  • Webhooks will be retried for up to 30 minutes with exponential backoff
  • If delivery fails after 30 minutes, no further retries will occur
  • Always implement polling as a fallback mechanism
If your webhook endpoint restricts inbound traffic by IP, make sure to allowlist Rightfoot’s outbound IPs. See IP Allowlisting.

Webhook Response

Your webhook endpoint should respond with an HTTP 2xx status code to confirm receipt:
{
  "status": "received"
}
If a 2xx response is not received, the webhook will be retried with exponential backoff for up to 30 minutes.

Implementing a Webhook Endpoint

Here are examples of implementing a webhook endpoint in various languages:
from flask import Flask, request, jsonify
import logging

app = Flask(__name__)

@app.route('/webhook/balance-batch-complete', methods=['POST'])
def handle_balance_webhook():
    try:
        # Parse the webhook payload
        data = request.get_json()
        
        # Validate required fields
        if not all(k in data for k in ['event_uuid', 'type', 'batch_id']):
            return jsonify({'error': 'Missing required fields'}), 400
        
        # Verify the event type
        if data['type'] != 'BALANCE_BATCH_COMPLETED':
            return jsonify({'error': 'Unexpected event type'}), 400
        
        # Log the event
        logging.info(f"Balance batch completed: {data['batch_id']}")
        
        # Process the completed batch (fetch results, update database, etc.)
        process_completed_batch(data['batch_id'])
        
        # Return success response
        return jsonify({'status': 'received'}), 200
        
    except Exception as e:
        logging.error(f"Webhook processing error: {str(e)}")
        return jsonify({'error': 'Internal server error'}), 500

def process_completed_batch(batch_id):
    # Fetch balance results using the batch_id
    # Update your database
    # Trigger any downstream processes
    pass

Retry Mechanism

The webhook delivery system implements exponential backoff:
  1. Initial attempt - Immediate
  2. First retry - After 1 minute
  3. Second retry - After 2 minutes
  4. Third retry - After 4 minutes
  5. Subsequent retries - Doubling interval up to 30 minutes total
After 30 minutes, no further retry attempts will be made.

Security Considerations

To secure your webhook endpoint:
  1. Use HTTPS - Always use SSL/TLS encryption for your webhook endpoint
  2. Validate payloads - Check that all required fields are present
  3. Implement idempotency - Handle duplicate webhook deliveries gracefully
  4. Add authentication - Consider implementing webhook signatures or API keys
  5. Rate limiting - Protect against potential abuse

Fallback Strategy

Since webhook delivery is not guaranteed, implement a polling fallback:
import time
import requests

def wait_for_batch_completion(batch_id, api_key, max_wait=3600):
    """
    Poll for batch completion with exponential backoff
    """
    start_time = time.time()
    poll_interval = 30  # Start with 30 seconds
    
    while time.time() - start_time < max_wait:
        # Check if batch is complete
        response = requests.get(
            f"https://api.rightfoot.com/v1/balances?batchId={batch_id}&limit=1",
            headers={"Authorization": f"Bearer {api_key}"}
        )
        
        if response.status_code == 200:
            # Batch is complete
            return True
        elif response.status_code == 404:
            # Batch still processing
            time.sleep(poll_interval)
            poll_interval = min(poll_interval * 1.5, 300)  # Cap at 5 minutes
        else:
            # Handle error
            raise Exception(f"Error checking batch status: {response.status_code}")
    
    return False  # Timeout reached

Best Practices

  1. Always implement polling - Don’t rely solely on webhooks
  2. Handle duplicates - Your system should be idempotent
  3. Log all events - Keep an audit trail of webhook receipts
  4. Monitor failures - Set up alerts for webhook processing errors
  5. Process asynchronously - Return 200 quickly and process in the background

Body

application/json
event_uuid
string
required

Unique identifier for the webhook event.

Example:

"f47ac10b-58cc-4372-a567-0e02b2c3d479"

type
string
required

The type of the webhook event, typically BALANCE_BATCH_COMPLETED.

Example:

"BALANCE_BATCH_COMPLETED"

batch_id
string
required

The ID of the batch that was processed.

Example:

"5d3c6bbb-fc1a-46a4-93da-1ce4a54b0d83"