Skip to main content
Webhooks are HTTP POST requests sent automatically by Truv when events occur during the verification flow. They track Task status changes, Order updates, Link connections, and data object creation, keeping your system in sync as data progresses through processing stages.
Configure webhook endpoints separately for Sandbox and Production.

Set up webhooks

Configure webhook endpoints in the Truv Dashboard:
  1. Navigate to DevelopmentWebhooks
  2. Enter your endpoint URL
  3. Save the configuration
Your endpoint will begin receiving webhook events for all activity in that environment.

Test webhooks

  • Use Truv Bridge in the Dashboard Emulator to trigger webhook events in sandbox
  • Use tools like ngrok to expose a local development server:
ngrok http 3000
Then configure the ngrok URL as your webhook endpoint in the Dashboard.

Webhook payload structure

All webhook requests include these standard fields:

Headers

HeaderValue
User-AgentTruv-Webhook-Service/2.0
X-WEBHOOK-SIGNHMAC-SHA256 signature for verification
HTTP header names are case-insensitive per RFC 7230.

Body Fields

Every webhook payload includes these common fields:
FieldDescription
webhook_idUnique identifier for this webhook request
event_typeThe event classification (see Events Reference)
event_created_atTimestamp when the event occurred
updated_atTimestamp for sequencing events
user_idAssociated Truv user identifier
template_idAssociated template, if applicable (nullable)
Additional fields vary by event type. See the event reference pages for Orders, Tasks, and Account Links.

Example Payload

{
  "webhook_id": "488f424096d3461aa0e4cf11a985f6df",
  "task_id": "521442a087604e599c637db310d07402",
  "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21",
  "product": "income",
  "data_source": "payroll",
  "tracking_info": null,
  "event_type": "task-status-updated",
  "event_created_at": "2022-08-24T13:55:12.845645Z",
  "updated_at": "2022-08-24T13:55:12.845666+00:00",
  "status": "parse",
  "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc",
  "template_id": null
}

Event types

Truv sends webhooks for these categories of events. See the dedicated event reference pages for full payloads and field descriptions.

Order Events

order-status-updated, order-refresh-failed

Task Events

task-status-updated and all data object events (employment-created, statements-created, etc.)

Account Link Events

link-connected, link-disconnected, link-deleted

Security

Every webhook includes an X-WEBHOOK-SIGN header with an HMAC-SHA256 signature. Verify it against the raw request body using your Access Secret before processing the event.
Always verify signatures using the raw request body, not parsed JSON. Parsing and re-serializing may change the byte representation.
See Webhook Security for verification code examples in Python, Node.js, Go, Ruby, and C#, along with IP allowlisting and delivery behavior details.

Timeouts and retries

BehaviorDetail
TimeoutYour endpoint must respond with a 2xx status within 10 seconds
Redirects3xx responses are followed
Retries4xx and 5xx responses trigger up to 3 retry attempts at 30-second intervals
BlockingAfter 3 consecutive failures, webhook delivery to your endpoint is blocked

Event ordering

Webhooks are delivered in event order. For example, full_parse fires before done. However, network conditions can cause delays in delivery.
Use the updated_at field to sequence events correctly in your system, rather than relying on delivery order.

Handle webhooks

Best Practices

Return a 200 response quickly. Process the webhook data asynchronously if needed:
app.post("/webhooks/truv", (req, res) => {
  // Acknowledge immediately
  res.status(200).send("OK");

  // Process asynchronously
  queue.add("process-webhook", req.body);
});
Webhooks may be delivered more than once. Use the webhook_id field for idempotency:
async function handleWebhook(payload) {
  const exists = await db.webhooks.findOne({
    webhookId: payload.webhook_id
  });

  if (exists) return; // Already processed

  await processEvent(payload);
  await db.webhooks.insert({ webhookId: payload.webhook_id });
}
Never process a webhook without verifying the X-WEBHOOK-SIGN header. See Security above.
The task-status-updated event is the primary signal for monitoring connection progress. Key statuses to handle:
  • done: All data has been downloaded and processed. Fetch verification reports.
  • login_error: Authentication failed. The user may need to retry.
  • mfa_error: MFA verification failed.
  • config_error: Provider configuration issue.
See Connection Lifecycle for the full status flow.

Troubleshooting

IssueSolution
Not receiving webhooksVerify your URL is configured under DevelopmentWebhooks for the correct environment
Signature verification failingEnsure you’re using your Access Secret (not Client ID) and hashing the raw body
TimeoutsRespond with 200 immediately, process asynchronously
Blocked endpointCheck for 3+ consecutive failures. Fix the issue and reconfigure the endpoint

Endpoints

Use the endpoints below to manage webhooks programmatically.

Next steps

Connection Lifecycle

Understand task status flow and error states