Skip to main content

Implementation Overview

Implementation Type: Kombo-based Integration
Note Format: Plain Text (Shortened due to character limits)
Status: Production Ready
Jobvite integrates through Kombo’s unified API, providing automatic implementation of most core functionality. This client includes custom implementations for enhanced job data, custom field management, requisition ID handling, and optimized note formatting to work within Jobvite’s character limits.

Configuration

PropertyValueDescription
Provider EnumjobviteIdentifier in ProviderEnum
Note FormatPLAINText-only notes (no HTML)
Disposition ReasonsSupportedCan retrieve and use rejection reasons
All Application StagesSupportedCan fetch all available stages
Passthrough URL/passthrough/jobvite/apiKombo passthrough endpoint

Jobvite-Specific Features

Internal Job Titles

Fetch internal job titles from custom fields separate from public job postings

Requisition ID Tracking

Automatic requisition ID extraction and appending to job names

Multi-Status Job Fetching

Retrieve jobs across all statuses (Open, Closed, Filled, On Hold, etc.)

PageType Custom Fields

Custom fields organized by pageType (Apply, Candidate, Requisition)

Feature Coverage

Streaming Operations

Stream Jobs

Status: Supported (Custom Implementation)
Method: _stream_jobs(updated_after, statuses)
Streams jobs from Jobvite via Kombo with custom requisition ID handling.Custom Enhancement: _get_req_id_for_streaming(job) fetches requisitionId from Jobvite passthrough API and appends it to job names.

Stream Applications

Status: Supported (Inherited)
Method: _stream_applications(updated_after, for_job_ids)
Streams applications from Jobvite via Kombo. Automatically inherited from BaseKomboAtsClient.

Stream Candidates

Status: Supported (Inherited)
Method: _stream_candidates(updated_after)
Streams candidates from Jobvite via Kombo. Automatically inherited from BaseKomboAtsClient.

Move Application to Stage

Status: Supported (Inherited)
Method: _move_application_to_stage(application, stage)
Moves applications between stages using Kombo’s unified API.

Get Disposition Reasons

Status: Supported (Inherited)
Method: get_disposition_reasons()
Retrieves rejection reasons from Jobvite through Kombo.

Reject Application

Status: Supported (Inherited)
Method: reject_application(application_id, reason_id)
Rejects a single application with optional rejection reason.

Bulk Reject Applications

Status: Supported (Inherited)
Method: bulk_reject_applications(application_ids, reason_id)
Bulk rejection of multiple applications.

Create Application

Status: Supported (Inherited)
Method: _create_application_for_candidate(candidate, job)
Creates new application records for candidates.

Get All Application Stages

Status: Supported (Inherited)
Method: _get_all_application_stages()
Fetches all available application stages from Jobvite.

Get Job by ID

Status: Supported (Inherited)
Method: get_job_by_job_id(job_id)
Retrieves a single job by its ID through Kombo.

Get Enhanced Job

Status: Supported (Custom Implementation)
Method: get_enhanced_job(kombo_id, remote_job_id)
Implementation Notes:
Custom implementation that fetches full job data including Jobvite-specific fields and custom fields via passthrough API.
Retrieves:
  • Job requisition ID from requisitionId field
  • All job statuses (Open, Closed, Filled, On Hold, Awaiting Approval, Approved, Rejected, Retracted, Draft)
  • Custom fields via customField array
  • Recruiter assignments
  • Salary information
  • Posting type (Internal/External)
Helper Method: get_jobvite_job(remote_job_id) - Fetches raw Jobvite job data with all statuses

Batch Jobs

Status: Supported (Custom Implementation)
Method: _get_specific_ats_jobs_batch(limit, include_closed, cursor)
Implementation Notes:
Custom batch fetching that queries Jobvite’s passthrough API directly. Handles pagination and job status filtering.
  • Default behavior: Only fetches “Open” jobs
  • With include_closed=True: Fetches all job states
  • Adds id field mapping (eIdid) for compatibility with base class

Get Internal Job Name

Status: Supported (Custom Implementation)
Method: get_job_internal_name(remote_job_id)
Unique to Jobvite:
Retrieves the value of the “internal_title” custom field, allowing jobs to have separate internal names vs. public posting titles.
Returns None if no internal_title custom field is found.

Get Candidate by ID

Status: Supported (Inherited)
Method: _get_candidate_by_id(candidate_id)
Retrieves candidate information from Jobvite via Kombo.

Find Candidates by Details

Status: Supported (Inherited)
Method: _find_candidates_by_details(first_name, last_name, email, phone)
Searches for candidates by name, email, or phone number.

Get Resume

Status: Supported (Inherited)
Method: _get_resume_for_candidate_id(candidate_id)
Retrieves candidate resume data through Kombo.

Add Note to Application

Status: Supported (Custom Implementation)
Method: _add_note_to_application(application, note, note_action_type)
Custom Implementation:
Uses Jobvite’s comments field via passthrough API. Updates applications using PUT request with candidate.application.comments structure.
Important: Uses shortened note format (see Note Format Limitation below).

Create Call Summary Note

Status: Supported (Custom Implementation)
Method: _create_plain_text_summary_from_call(call)
Custom Implementation:
Generates plain text summary notes without transcripts to stay within Jobvite’s character limit. Set to include_transcript=False.

Add Note to Candidate

Status: Supported (Inherited)
Method: _add_note_to_candidate(candidate, note, note_action_type)
Adds plain text notes to candidate records.

Add Attachment to Application

Status: Supported (Inherited)
Method: _add_attachment_to_application(filename, application_id, pdf_b64)
Uploads attachments (PDFs, resumes, etc.) to applications.

Add Attachment to Candidate

Status: Supported (Inherited)
Method: _add_attachment_to_candidate(filename, candidate_id, pdf_b64)
Uploads attachments to candidate records.

Application Custom Fields

Status: Fully Supported (Custom Implementation)
Methods:
  • _get_application_custom_fields() - Get field definitions via /customfield?objectType=Candidate
  • _update_application_custom_fields(application, updates) - Update via PUT /candidate
Implementation Notes:
Fetches custom fields from Jobvite passthrough API and processes them using process_jobvite_custom_fields() which:
  • Deduplicates fields by fieldCode
  • Prioritizes pageType=Apply fields over other pageTypes
  • Extracts fieldCode as remote_id and displayName as remote_name
Updates use Jobvite’s nested payload structure:
{
  "candidate": {
    "application": {
      "eId": "application_id",
      "customField": [
        {"fieldCode": "field_id", "value": "new_value"}
      ]
    }
  }
}

Candidate Custom Fields

Status: Read-Only Support (Routes to Application Endpoint)
Available Methods:
  • get_custom_fields(AtsEntityType.CANDIDATE) - Routes to _get_application_custom_fields()
Missing (Jobvite API Limitation):
  • _update_candidate_custom_fields() - Inherits NotImplementedError from BaseKomboAtsClient
Implementation Notes:
The get_custom_fields() method routes both APPLICATION and CANDIDATE entity types to the same endpoint (/customfield?objectType=Candidate), as Jobvite treats these similarly. Custom field names include pageType suffix for clarity (e.g., “Phone Number (Application)” vs “Phone Number (Candidate Profile)”).

Job Custom Fields

Status: Read-Only Support (Custom Implementation)
Available Methods:
  • _get_job_custom_fields() - Get field definitions via /customfield?objectType=Job
  • _get_job_custom_field_values(job_id) - Get field values from job data
Missing (Jobvite API Limitation):
  • _update_job_custom_fields() - Inherits NotImplementedError from BaseKomboAtsClient
Implementation Notes:
Job custom fields use build_internal_representation_job_custom_fields() which:
  • Filters for pageType=Requisition fields only
  • Deduplicates by fieldCode
  • Maps field types using FieldTypeMapper

Jobvite Data Model

JobviteJob Structure

The JobviteJob dataclass extends AtsJob with 17 Jobvite-specific fields:
class JobviteJob(AtsJob):
    provider: Literal["jobvite"] = "jobvite"
    
    # Jobvite Identifiers
    eId: str                      # Jobvite entity ID
    requisitionId: str            # Human-readable req ID (appended to job name)
    companyId: str                # Company identifier
    
    # Job Classification
    category: str                 # Job category
    jobType: str                  # Full-time, Contract, etc.
    jobState: str                 # Open, Closed, Filled, On Hold, etc.
    openings: str                 # Number of openings
    
    # Salary Information
    salaryCurrency: str
    salaryFrequency: str
    salaryMin: str
    salaryMax: str
    
    # Links and Posting
    applyLink: str                # External apply URL
    detailLink: str               # Job details URL
    postingType: str              # "Internal" or "External"
    internalOnly: bool            # Posting visibility flag
    is_external: bool             # Computed: postingType == "external" or not internalOnly
    
    # Related Data
    recruiters: list[JobviteJobRecruiter]       # Assigned recruiters
    custom_field_values: list[CustomFieldValue]  # Custom field data

JobviteJobRecruiter Structure

class JobviteJobRecruiter:
    email: str
    firstName: str
    lastName: str
    userId: str
    userName: str
    employeeId: str

Implementation Notes

Requisition ID Handling

Jobvite stores requisition IDs in the requisitionId field. Our implementation automatically appends this to job names for display:
"Senior Engineer" → "Senior Engineer (REQ-2024-001)"
The req ID is extracted via:
  • Enhanced jobs: _get_req_id_for_job(job, raw_data) from passthrough data
  • Streaming jobs: _get_req_id_for_streaming(job) via additional API call

Custom Field PageType Architecture

Jobvite organizes custom fields by pageType:
PageTypeDescriptionUsed For
ApplyApplication form fieldsApplication custom fields (prioritized)
CandidateCandidate profile fieldsCandidate custom fields
RequisitionJob/requisition fieldsJob custom fields
Our process_jobvite_custom_fields() method:
  1. Deduplicates fields by fieldCode
  2. Prioritizes Apply pageType when duplicates exist
  3. Adds pageType suffix to field names for clarity

Multi-Status Job Fetching

Important: Jobvite API defaults to returning only “Open” jobs. Our implementation explicitly passes all job statuses when fetching job data:
Supported statuses:
  • Open
  • Closed
  • Filled
  • On Hold
  • Awaiting Approval
  • Approved
  • Rejected
  • Retracted
  • Draft
The get_jobvite_job() method constructs status parameters like:
?ids={job_id}&jobStatus=Open&jobStatus=Closed&jobStatus=Filled...

Internal Job Titles

Jobvite supports a special internal_title custom field that allows jobs to have different internal vs. external names. Use get_job_internal_name() to retrieve this value. Use cases:
  • Hide sensitive project codenames from external candidates
  • Use simplified internal references
  • Maintain different naming conventions for internal tracking

Known Limitations

Note Character Limit
Jobvite has a strict character limit on application notes. To work within this constraint, our _create_plain_text_summary_from_call() method generates shortened summaries WITHOUT transcripts (include_transcript=False). Full interview transcripts are available as attachments if needed.
Custom Field Update Limitations (Jobvite API)
  • Candidate custom fields: Read-only. Updates not supported by Jobvite API through Kombo.
  • Job custom fields: Read-only. Updates not supported by Jobvite API through Kombo.
  • Application custom fields: Fully supported (read and write).
Kombo Dependency
This integration relies on Kombo’s Jobvite connection. Any Kombo service issues will affect this integration’s availability.

Error Handling

Jobvite API errors are nested inside Kombo’s 200 OK response. We parse the nested status code in parse_and_validate_kombo_response(). When debugging, check both the outer Kombo status AND the inner Jobvite response. Example of nested error:
{
  "status": 200,  // Kombo says OK
  "data": {
    "status": 400,  // But Jobvite rejected it!
    "data": {
      "message": "Invalid field value"
    }
  }
}
  • Implementation: server/ats/jobvite_ats_client.py (~625 lines)
  • Data Models: JobviteJob, JobviteJobRecruiter, JobviteJobLocation
  • Field Mappings: server/ats/field_type_mapper.py (JOBVITE_FIELD_MAPPINGS)
  • Base Class: server/ats/base_kombo_ats_client.py
  • Registration: server/ats/ats_factory.py

See Also