Skip to main content
TruEnroll delivers results by pushing events to your registered HTTPS endpoint rather than requiring you to poll for status changes. Each processing stage emits its own event when it reaches a terminal state — completed or failed.

Registering a webhook endpoint

Webhook endpoints are provisioned for your organization by your TruEnroll account manager. You’ll specify:
  • The HTTPS URL TruEnroll should POST to
  • The audience type: partner (required for Partner API events)
Partner events are only delivered to endpoints with audience: partner. Internal platform events are not mixed into partner webhook delivery.

Event names

EventFired when
case.classification.completedDocument classification succeeded
case.classification.failedDocument classification failed (terminal)
case.extraction.completedExtraction succeeded; structured data is ready
case.extraction.failedExtraction failed (terminal)
case.forensics.completedForensics analysis succeeded
case.forensics.failedForensics analysis failed (terminal)
case.translation.completedTranslation succeeded; output is ready
case.translation.failedTranslation failed (terminal)
You only receive events for features you requested. If you submitted a case with features=["extraction","forensics"], you won’t receive case.translation.* events.

Event payload

All events share the same envelope:
{
  "eventName": "case.extraction.completed",
  "payload": {
    "caseId": "6850abc123def456ghi789",
    "externalId": "applicant-9876",
    "occurredAt": "2025-06-22T10:30:00Z"
  }
}
eventName
string
The event name from the table above. Use this to route incoming events in your handler.
payload.caseId
string
TruEnroll’s unique case identifier. Use this to call the result endpoint.
payload.externalId
string | null
The externalId you provided at submission time, or null if none was provided.
payload.occurredAt
string (ISO 8601)
The timestamp when the processing event occurred internally.

Event ordering

Events for different features within the same case arrive independently and in any order — forensics and extraction run in parallel, so case.forensics.completed may arrive before case.extraction.completed or vice versa. Do not assume ordering between events for different features. Handle each event on its own merits. Events for the same feature on the same case are ordered — you won’t receive case.extraction.completed before case.extraction.failed for the same document.

Idempotency

TruEnroll guarantees that each terminal event for a given case is dispatched at most once. Even so, your endpoint should be idempotent — network infrastructure can retry deliveries. Design your handler so that processing the same event twice produces the same outcome.

Handling events

A minimal webhook handler:
app.post('/truenroll/webhook', express.json(), async (req, res) => {
  // Acknowledge immediately — TruEnroll will retry if it doesn't get 2xx
  res.sendStatus(200);

  const { eventName, payload } = req.body;

  switch (eventName) {
    case 'case.extraction.completed':
      await handleExtractionComplete(payload.caseId, payload.externalId);
      break;
    case 'case.extraction.failed':
      await handleExtractionFailed(payload.caseId, payload.externalId);
      break;
    case 'case.forensics.completed':
      await handleForensicsComplete(payload.caseId);
      break;
    // handle remaining events...
  }
});
Respond with 2xx before doing work. TruEnroll considers delivery successful when your endpoint returns a 2xx status. If your handler times out or throws before responding, TruEnroll will retry the delivery. Acknowledge first, then process asynchronously.

Classification suppression

If you submitted an upload with classify: false, TruEnroll will not emit case.classification.completed or case.classification.failed events for that upload.

What to do when a stage fails

A case.*.failed event means that stage is done and won’t be retried automatically. Other stages may still complete: You can still call the result endpoints for stages that succeeded. Use the overall case status (GET /cases/{id}) to determine whether to resubmit or flag for manual review.