← Help Center

Webhook Integration Guide

Receive real-time updates about candidate interactions via HTTP POST callbacks.

Overview

TalentPrism webhooks allow you to receive real-time updates about candidate interactions and interview progress. Events are delivered as HTTP POST requests to your specified endpoint with a JSON payload.

For interview events, metadata.client_metadata.client_job_id is resolved from the specific interview when possible. This matters for generic sequences where one public sequence can serve many client jobs.

Setting Up Webhooks

  1. Configure your endpoint URL in the sequence settings
  2. Save the webhook secret that is generated
  3. Use the test endpoint to verify your setup

Security

All webhook requests include an X-Talentprism-Signature header containing your webhook secret. You should verify this signature to ensure the request came from TalentPrism.

Event Types

Touchpoint Events

Event Description
touchpoint.sentMessage has been sent
touchpoint.deliveredMessage was delivered
touchpoint.respondedCandidate replied to message
touchpoint.failedMessage delivery failed
touchpoint.undeliveredMessage could not be delivered
touchpoint.unsubscribedCandidate opted out
touchpoint.rejectedMessage rejected by provider

Interview Events

Event Description
interview.interview_completedInterview submitted by candidate
interview.interview_openedInterview opened by candidate
interview.resume_uploadedResume uploaded
interview.interview_consent_selectionAI interview consent selection

How client_metadata Is Resolved

Webhook payloads start from sequence-level metadata and may be enriched with candidate-level metadata. Interview events add one extra rule so the job id stays tied to the correct application.

  1. Base payload uses sequence.client_metadata.
  2. Candidate metadata may add extra keys for the same candidate.
  3. For interview events, client_job_id is resolved from the current interview context before any legacy candidate-level fallback is used.
  4. Internal application history stored under candidate.client_metadata.applications is not emitted in the webhook payload.

Testing

To test your webhook integration, send a POST request to:

POST /sequence/sequences/{sequence_id}/test-webhook/

Example Payload

{
    "event_id": "evt_12345678",
    "event_type": "touchpoint.responded",
    "created_at": "2025-04-22T15:30:45Z",
    "data": {
        "channel": "email",
        "candidate": {
            "id": "cand_12345",
            "screenname": "John Doe",
            "email": "[email protected]"
        },
        "touchpoint": {
            "id": "tp_87654321",
            "status": "responded"
        },
        "response": {
            "responded_at": "2025-04-22T15:30:40Z",
            "content": "Yes, I'm interested"
        }
    },
    "metadata": {
        "account_id": "acct_12345",
        "version": "1.0"
    }
}

Interview Payload Example

All people, companies, identifiers, URLs, and timestamps in this example are synthetic.

{
    "event_id": "evt_12345678",
    "event_type": "interview.interview_completed",
    "created_at": "2026-03-14T20:31:03Z",
    "data": {
        "channel": "webCall",
        "candidate": {
            "candidate_id": 12345,
            "screenname": "John Smith",
            "first_name": "John",
            "last_name": "Smith",
            "email": "[email protected]",
            "phone": null
        },
        "interview": {
            "interview_id": "00000000-0000-4000-8000-000000000001",
            "candidate_id": 12345,
            "status": "completed",
            "public_url": "https://talentprism.ai/candidate/interview/example-token/"
        },
        "response": {
            "interview_opened_at": "2026-03-14T20:30:00Z",
            "interview_exited_at": "2026-03-14T20:31:00Z"
        }
    },
    "metadata": {
        "account": "Example Staffing Co",
        "job_title": "Welder Application Intake",
        "client_metadata": {
            "company_name": "Example Staffing Co",
            "client_job_id": "JOB-12345",
            "jobs_list_url": "https://example.com/jobs.json",
            "jobs_page_url": "https://example.com/jobs",
            "job_page_url_format": "https://example.com/jobs/{job_id}",
            "referral_fee": "$200",
            "referral_hours_requirement": "160 hours"
        },
        "version": "1.0"
    }
}

Payload Data Fields

The data object contains event-specific information. A top-level channel field is always included:

Value Description
"email"Email-based touchpoints (from Outreach Message)
"sms"SMS-based touchpoints (from Outreach Message)
"inboundPhoneCall"Interview events conducted via phone
"webCall"Interview events conducted via web interface
"unknown"Channel cannot be determined

Webhook Payload Schema Tree

Webhook Payload
├── event_id (string)
├── event_type (string)
├── created_at (string - ISO 8601 datetime)
├── data
│   ├── channel (string: "email" | "sms" | "phone" | "web" | "unknown")
│   ├── candidate
│   │   ├── id (string)
│   │   ├── screenname (string)
│   │   ├── first_name (string)
│   │   ├── last_name (string)
│   │   ├── email (string)
│   │   └── phone (string)
│   │
│   ├── touchpoint (object - present for touchpoint.* events)
│   │   ├── id (string)
│   │   ├── candidate_id (string)
│   │   ├── outreach_message_id (string)
│   │   ├── channel (string: "email" | "sms")
│   │   └── status (string)
│   │
│   ├── interview (object - present for interview.* events)
│   │   ├── id (string)
│   │   ├── candidate_id (string)
│   │   └── status (string)
│   │
│   └── response (object - structure varies by event_type)
│       │
│       ├── IF touchpoint.responded:
│       │   ├── responded_at (ISO 8601 datetime)
│       │   ├── content (string)
│       │   └── ai_analysis (object | null)
│       │
│       ├── IF touchpoint.failed:
│       │   ├── failed_at (ISO 8601 datetime)
│       │   ├── reason (string)
│       │   └── recipient_status (string | null)
│       │
│       └── IF interview.interview_completed:
│           ├── interview_opened_at (ISO 8601 datetime | null)
│           ├── interview_exited_at (ISO 8601 datetime | null)
│           ├── language_selected (string | null)
│           ├── content (string - transcript)
│           └── ai_analysis (object)
│               ├── total_questions (integer)
│               ├── total_duration_minutes (integer | null)
│               ├── overall_score (number | null)
│               └── recommendation (string | null)
│
└── metadata
    ├── account (string)
    ├── job_title (string)
    ├── client_metadata (object)
    │   ├── sequence-level metadata keys
    │   ├── candidate-level enrichment keys
    │   └── client_job_id resolved from the current interview for interview events
    └── version (string)

Can't find what you're looking for?

Contact Us