Overview
Webhooks allow you to receive real-time notifications when specific events occur in your TitanX account. Instead of polling our API for changes, webhooks push data to your server as events happen, enabling you to build responsive, event-driven integrations.Understanding Webhook Documentation:
- Webhook Management API - Endpoints you call to create, list, update, and delete webhook subscriptions
- Webhook Callbacks - Documentation of the events TitanX sends to your webhook endpoints
- This guide - Step-by-step instructions for implementing webhooks
How Webhooks Work
- Configure a webhook - Set up an HTTPS endpoint URL and subscribe to specific event types
- Events occur - When an event happens (e.g., a contact is scored), TitanX creates an event
- TitanX sends a POST request - We send the event data to your webhook URL with an HMAC signature
- Your server responds - Your endpoint processes the event and returns a 2xx status code
- Acknowledgment - We consider the delivery successful when we receive a 2xx response
Supported Events
job.contact.scored
Fired when a contact completes the scoring process. This event provides the full contact object with all phone numbers annotated with their propensity scores. When it fires:- After a contact has been fully processed and scored
- For all of your contacts regardless of how they were submitted — via the scoring API or the TitanX App
- Only for contacts belonging to the authenticated user
job.completed
Fired once per job, after the job reaches a terminal state — either all contacts were scored, or all contacts were rejected during enrichment (finalized as “Not Enriched”). This is a job-level bookkeeping signal that the batch is done — it carries no contact data. Your contact results are delivered separately and in real time viajob.contact.scored (one event per contact); job.completed is just an optional checkpoint to know a whole batch has finished — for progress tracking or reconciliation — and is not required to receive results.
See the job.completed callback reference for the full payload specification.
Webhook Payload Structure
All webhook events follow a consistent structure:Fields
payload- The event data. Forjob.contact.scoredevents, contains acontactkey with the full Contact object (see the Webhook Callbacks reference for the complete field list)payload.contact- The complete scored Contact object with all available fieldspayload.job- Context about the job that triggered this eventpayload.job.id- The ID of the originating job. Use this to correlate events back to a specific job. May benullfor legacy events.payload.job.type- The type of job that produced this event. Use this to route handling logic, as different job types annotate different fields. May benullfor legacy events.eventType- The type of event (such as “job.contact.scored”)timestamp- Unix timestamp in milliseconds when the event occurredapiVersion- API version (currently “v2”)id- Unique identifier for this webhook event (use for idempotency)
Example: job.contact.scored Payload
Thepayload.contact contains the complete Contact object with all fields. Here’s an example with commonly used fields:
The complete Contact object includes 60+ fields covering contact details, phone numbers, address information, company firmographics, and more. Phone data is provided in the canonical
phones[] array — each entry includes number, status, type, country, region, position, and ivrPath, and the array also surfaces enrichment phones beyond the five-number cap. The flat phone/phone2–phone5 fields (and their Status/Type/Country/Region variants) remain for backward compatibility but are deprecated. See the Webhook Callbacks reference for the exhaustive field list.Security: Verifying Webhook Signatures
Every webhook request includes anX-TitanX-Signature header containing an HMAC-SHA256 signature. You must verify this signature to ensure the request came from TitanX and hasn’t been tampered with.
Signature Format
The signature is computed as:Verification Example (Node.js)
Verification Example (Python)
Setting Up Webhooks
Step 1: Create Your Webhook Endpoint
Create an HTTPS endpoint that:- Accepts POST requests
- Verifies the
X-TitanX-Signatureheader - Returns a 2xx status code within 10 seconds
- Handles events idempotently (using the event
idfield)
For detailed information about the webhook callback format and fields, see the Webhook Callbacks documentation.
Step 2: Create the Webhook via API
Use the Create Webhook endpoint from the Webhook Management API:secret which is only shown once. Store it securely - you’ll need it to verify webhook signatures.
Step 3: Test Your Webhook
After creating your webhook, score some contacts via the API and verify your endpoint receives the events.Rate Limiting
Webhooks are subject to rate limiting to prevent overwhelming your servers:- Default rate limit: 5 requests per second per user
- Configurable: Rate limits can be adjusted via entitlements
- Flow control: Webhooks for the same user and event type share a rate limit key
Best Practices
1. Respond Quickly
Return a 2xx status code as soon as you receive the webhook. Process the event asynchronously if needed:2. Implement Idempotency
Use the eventid to prevent processing duplicate events:
3. Handle Errors Gracefully
If your endpoint returns a non-2xx status code, we’ll consider the delivery failed. Implement retry logic in your application for transient failures.4. Monitor Webhook Health
- Log all webhook events for debugging
- Monitor success/failure rates
- Set up alerts for consistent failures
- Use the webhook
statusendpoint to pause webhooks during maintenance
5. Use HTTPS
Webhook URLs must use HTTPS. This ensures:- Data is encrypted in transit
- Your endpoint is authenticated
- Man-in-the-middle attacks are prevented
Managing Webhooks
List All Webhooks
Update Webhook Status
Pause a webhook without deleting it:Delete a Webhook
Understanding Contact Scores
When you receive ajob.contact.scored event, the contact will include phone status annotations:
Phone Statuses
The status of the phone number
IVR stands for Interactive Voice Response, which you may know as a dial tree
Lead Status
Each contact has an overallleadStatus field that represents the highest scoring phone number:
The overall status of the contact based on the highest scoring phone status.
Troubleshooting
Webhook Not Firing
- Verify the webhook status is “active”
- Check that contacts belong to the authenticated user (the event fires for both API- and App-submitted contacts, so the source is not the issue)
- Verify your endpoint is accessible from the internet
Signature Verification Failing
- Ensure you’re using the raw request body (not parsed JSON)
- Verify you’re using the correct webhook secret
- Check that you’re computing Base64-encoded HMAC-SHA256
- Verify the signature header name is exactly
X-TitanX-Signature
Timeouts
- Return a 2xx response within 10 seconds
- Process events asynchronously if they take longer
- Consider using a message queue for complex processing
Need Help?
If you have questions or need assistance with webhooks:- Email: support@titanx.io
- Check our API Reference for detailed endpoint documentation