Overview

Webhooks allow you to receive real-time notifications when events occur in your GetBill account. Instead of repeatedly polling the API for changes, webhooks push updates directly to your application, making your integration more efficient and responsive.

How Webhooks Work

Setting Up Webhooks

1. Create a Webhook Endpoint

Your webhook endpoint must:
  • Accept POST requests
  • Return a 2xx status code (200-299) for successful processing
  • Respond within 10 seconds
  • Verify the webhook signature (recommended)

2. Configure Webhooks in GetBill

  1. Log in to your GetBill dashboard
  2. Navigate to Settings → External Services
  3. Scroll down to the Webhook Endpoints section
  4. Click Create New Webhook Endpoint
  5. Configure your webhook:
    • Name: A descriptive name (e.g., “CRM Integration”)
    • URL: Your webhook endpoint URL (e.g., https://yourapp.com/webhooks/getbill)
    • Description: Optional description of what this webhook does
    • Events: Select which events to receive (check the boxes for the event types you want)
  6. Click Create - a secret key will be automatically generated
  7. Important: Copy and save the secret key securely - you’ll need it for signature verification

Verifying Webhook Signatures

GetBill signs all webhook requests to ensure they’re authentic and haven’t been tampered with. You should always verify the signature before processing webhook events to protect your application from malicious requests.

How It Works

When GetBill sends a webhook to your endpoint, it includes a cryptographic signature in the request headers. Here’s the process:
  1. GetBill generates a signature: Using HMAC-SHA256 with your webhook secret key and the raw request body
  2. Signature is sent in header: The signature is included in the X-GetBill-Signature header
  3. You compute the same signature: Using the same algorithm, your secret key, and the raw request body
  4. Compare signatures: Use a timing-safe comparison function to verify they match

Signature Details

HMAC-SHA256
The cryptographic hash algorithm used to generate signatures
X-GetBill-Signature
The HTTP header containing the signature (lowercase hex string)
Raw Request Body
The exact raw JSON payload as received (before parsing)
Webhook Secret
The secret key generated when you created the webhook endpoint

Verification Steps

  1. Extract the signature from the X-GetBill-Signature header
  2. Get the raw request body (before JSON parsing)
  3. Compute HMAC-SHA256 hash of the raw body using your secret key
  4. Compare using a timing-safe comparison function (prevents timing attacks)
  5. Reject the request if signatures don’t match
Security Critical: Always use a constant-time comparison function (like crypto.timingSafeEqual() in Node.js, hmac.compare_digest() in Python, or hash_equals() in PHP) to prevent timing attacks. Never use simple string equality (== or ===).

Implementation Examples

The code examples in the sections above demonstrate proper signature verification. Key points:
  • Node.js: Use crypto.timingSafeEqual() with Buffer.from()
  • Python: Use hmac.compare_digest()
  • PHP: Use hash_equals()

Testing Signature Verification

You can test your signature verification with this example:
This will output the expected signature that should match what your endpoint computes.
Store your webhook secret securely (environment variable or secrets manager) and never commit it to version control. Treat it like a password!

Webhook Events

Available Event Types

  • debt.created - A new debt was created
  • debt.updated - A debt was modified. Use this when you need to sync debt details beyond collection progress.
  • debt.deleted - A debt was deleted
  • debt.status_changed - Debt status was updated. When the debt becomes paid because of a payment transaction, the payload also includes transaction context.
  • followup.created - A new followup was created
  • followup.updated - A followup was modified
  • followup.completed - A followup was marked as completed
  • followup.failed - A followup attempt failed
  • payment.received - A payment was recorded
  • payment.failed - A payment attempt failed
  • payment_plan.created - A payment plan was set up
  • payment_plan.completed - All payments in a plan were completed
  • payment_plan.canceled - A payment plan was canceled
  • company.credits_low - Credit balance is running low
  • integration.error - An integration error occurred

Event Payload Structure

All webhook events follow this structure:
string
Unique identifier for the webhook event (format: evt_[32 hex characters])
string
The type of event that occurred (e.g., debt.created, followup.completed)
string
When the event occurred (ISO 8601 format with timezone)
object
The actual data for the event (structure varies by event type - see examples below)
object
Additional context about the event including:
  • source: Always “getbill”
  • version: API version (currently “1.0”)
  • company_id: Your company ID
  • Additional fields depending on event type (e.g., debt_id, followup_id, payment_id)

Event Type Examples

Debt Events

debt.created

debt.updated

Use debt.updated when you need to keep debt details synchronized. For collection progress, prefer debt.status_changed.
The changes field is included when specific field changes are tracked. It shows the previous and new values for each modified field. This field may not be present for all updates.

debt.status_changed

data.status_change_context is optional. It is included only when the new status is a paid status and that transition was directly caused by a payment transaction.
  • provider_transaction_id is GetBill’s canonical transaction identifier for the provider.
  • provider_identifiers includes additional native provider IDs when available.
  • For Stripe, provider_identifiers may include checkout_session_id, payment_intent_id, and charge_id.
  • For Axepta, provider_identifiers may include pay_id and trans_id.
  • For Adyen, provider_identifiers may include payment_link_id and psp_reference.
  • For SumUp, provider_identifiers may include checkout_id and transaction_id.
  • For Bridge, provider_identifiers may include payment_link_id, payment_request_id, and client_reference.
  • For GoCardless, provider_identifiers may include event_id.
  • For Scellius, PayZen, and SystemPay, provider_identifiers may include order_id and transaction_uuid.
  • For Monetico, provider_identifiers may include numauto.
The status field uses translation key format status.default.* (not simple strings):Important Notes:
  • Format is always status.default.{name}, never just the name (e.g., "status.default.paid" not "paid")
  • Companies can create custom statuses with the status.custom.* prefix
  • When filtering or comparing status values, always use the full format

debt.deleted

Followup Events

followup.created

followup.updated

followup.completed

Media URLs: The audio_url and pdf_url fields contain presigned CloudFront URLs that expire after 1 hour (indicated by media_urls_expire_at). These URLs provide temporary access to call recordings and PDF documents. Important: Cache these URLs but refresh them before the expiration time if you need continued access.
The status field uses lowercase underscore format (e.g., deal_found, not DEAL_FOUND):Note: Always use lowercase format (e.g., "deal_found" not "DEAL_FOUND").

followup.failed

Payment Events

payment.received

payment.failed

payment_plan.created

payment_plan.completed

payment_plan.canceled

System Events

company.credits_low

integration.error

Handling Specific Events

Debt Events

Followup Events

Error Handling & Reliability

Automatic Retry Behavior

GetBill automatically handles webhook delivery retries for you. If your endpoint fails to respond with a 2xx status code or times out, GetBill will automatically retry with exponential backoff:
  • 1st retry: After 1 minute
  • 2nd retry: After 5 minutes
  • 3rd retry: After 30 minutes
After 3 failed attempts, the webhook delivery is marked as permanently failed. You can view the full delivery history and error details in your dashboard under Settings → External Services → Webhook Endpoints → Deliveries.
Important: Make sure your endpoint returns a 2xx status code (like 200 or 204) quickly, even if you queue the actual processing for later. GetBill waits up to 10 seconds for a response before timing out.

Monitoring Failed Deliveries

Monitor webhook delivery failures through your dashboard:
  1. Go to Settings → External Services
  2. Find your webhook endpoint
  3. Click Deliveries to see:
    • Delivery status for each event
    • HTTP status codes returned
    • Error messages for failures
    • Retry attempts and timing
    • Full request/response payloads
This helps you quickly diagnose and fix integration issues.

Idempotency

Ensure your webhook handlers are idempotent to handle duplicate deliveries:

Testing Webhooks

Local Development with ngrok

For local testing, use ngrok to expose your local server:

Testing Webhook Endpoints

Monitoring & Debugging

Monitoring Webhooks

Monitor webhook deliveries through your GetBill dashboard:
  • Delivery Status: Check webhook delivery success/failure rates
  • Event History: Review recent webhook events and their outcomes
  • Error Analysis: Investigate failed deliveries and common issues
  • Performance Metrics: Track response times and delivery patterns
For programmatic monitoring, you can implement your own logging and alerting based on webhook responses.

Security Best Practices

Verify Signatures

Always verify webhook signatures to ensure requests come from GetBill

Use HTTPS

Only accept webhooks over HTTPS to protect data in transit

Validate Payloads

Validate webhook payloads before processing to prevent malicious input

Rate Limiting

Implement rate limiting on your webhook endpoints to prevent abuse
Webhooks are a powerful way to keep your application in sync with GetBill in real-time. By following these guidelines and implementing proper error handling, you’ll have a robust integration that scales with your business needs.