> ## Documentation Index
> Fetch the complete documentation index at: https://f4c7a9e2d8b1-docs.tenzo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracker ATS

> Feature coverage and implementation details for Tracker integration

## Implementation Overview

**Implementation Type:** Direct API Integration\
**Note Format:** Plain Text\
**Status:** Production Ready

## Configuration

| Property               | Value                                                                      |
| ---------------------- | -------------------------------------------------------------------------- |
| Provider Enum          | `tracker`                                                                  |
| Note Format            | `PLAIN`                                                                    |
| Disposition Reasons    | **Not Supported** (empty list; no enumeration API)                         |
| All Application Stages | **Supported** (from Tracker metadata `opportunityResourceStatuses`)        |
| API Key                | Currently loaded from `settings.MW_RESOURCE_API_KEY` in `TrackerAtsClient` |

## Feature Summary

Direct API integration with comprehensive functionality. Notable limitations: no disposition-reason enumeration, and application rejection APIs are not wired through yet (see Application Management).

## Code-Verified Support Checklist

This checklist reflects the current `TrackerAtsClient` implementation.

| Capability                         | Status                        | Method(s)                                                                                  |
| ---------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------ |
| Stream Jobs                        | **Supported**                 | `_stream_jobs`, `stream_jobs_by_page`                                                      |
| Stream Applications                | **Supported**                 | `_stream_applications`, `stream_applications_by_page`                                      |
| Stream Candidates                  | **Supported**                 | `_stream_candidates`, `stream_candidates_by_page`                                          |
| Get Job by ID                      | **Supported**                 | `get_job_by_job_id`, `get_tracker_job_by_id`                                               |
| Get Application by ID              | **Supported**                 | `get_application_by_application_id`                                                        |
| Get Candidate by ID                | **Supported**                 | `_get_candidate_by_id`                                                                     |
| Move to Stage                      | **Supported**                 | `_move_application_to_stage`                                                               |
| Create Application                 | **Supported**                 | `_create_application_for_candidate`                                                        |
| Get All Application Stages         | **Supported**                 | `_get_all_application_stages` (`supports_get_all_application_stages = True`)               |
| Get Disposition Reasons            | **Not Supported**             | `get_disposition_reasons` returns `[]` (`supports_disposition_reasons = False`)            |
| Reject Application                 | **Not Supported**             | `reject_application` raises `NotImplementedError`                                          |
| Bulk Reject Applications           | **Not Supported**             | `bulk_reject_applications` returns empty `BulkRejectResult` (stub)                         |
| Get Resume                         | **Not Supported**             | `_get_resume_for_candidate_id` returns `None`                                              |
| Find Candidates                    | **Supported with limitation** | `_find_candidates_by_details` (name-driven search; email lookup is not used)               |
| Add Notes / Attachments            | **Supported (write path)**    | `_add_note_to_*`, `_add_attachment_to_*`                                                   |
| Read Custom Fields                 | **Supported**                 | `_get_application_custom_fields`, `_get_candidate_custom_fields`, `_get_job_custom_fields` |
| Update Candidate/App Custom Fields | **Supported**                 | `_update_candidate_custom_fields`, `_update_application_custom_fields`                     |
| Update Standard Job Fields         | **Not Supported**             | `_update_job_fields` raises `NotImplementedError`                                          |

<AccordionGroup>
  <Accordion title="Streaming Operations (All Supported)" defaultOpen>
    * Stream Jobs (Custom Implementation)
    * Stream Applications (Custom Implementation)
    * Stream Candidates (Custom Implementation)

    **Implementation Notes:**\
    Custom timezone adjustment logic subtracts 8 hours from `updated_after` timestamps because Tracker returns local time instead of UTC.
  </Accordion>

  <Accordion title="Application Management">
    ### Move to Stage

    **Status:** Supported (Custom Implementation)\
    **Method:** `_move_application_to_stage(application, stage)`

    Moves applications between stages using Tracker's API. Works with known stage IDs.

    ### Get Rejection Reasons

    **Status:** Not Supported\
    **Method:** `get_disposition_reasons()`

    Returns an empty list. `supports_disposition_reasons` is `False`; there is no usable enumeration of rejection reasons for the product flow.

    ### Reject Application

    **Status:** Not Supported (not implemented)\
    **Method:** `reject_application(application_id, reason_id)`

    Raises `NotImplementedError`. Stage moves (`_move_application_to_stage`) are the supported path for workflow updates.

    ### Bulk Reject Applications

    **Status:** Not Supported (stub)\
    **Method:** `bulk_reject_applications(application_ids, reason_id)`

    Returns an empty `BulkRejectResult` until batch rejection is implemented against Tracker's API.

    ### Create Application

    **Status:** Supported (Custom Implementation)\
    **Method:** `_create_application_for_candidate(candidate, job)`

    Creates new application records for candidates in Tracker.

    ### Get All Application Stages

    **Status:** Supported (Custom Implementation)\
    **Method:** `_get_all_application_stages()`

    Loads cached Tracker metadata and maps `opportunityResourceStatuses` to `ApplicationStage` objects. `supports_get_all_application_stages` is `True`.
  </Accordion>

  <Accordion title="Job Management (All Supported)">
    * Get Job by ID (Custom Implementation)
    * Get Enhanced Job (Custom Implementation)
    * Batch Job Operations (Custom Implementation)

    Job data includes Tracker-specific metadata like categories and custom workflows.
  </Accordion>

  <Accordion title="Candidate Management">
    * Get Candidate by ID (Custom Implementation)
    * Find by Details (Custom Implementation; currently name-based search in practice)
    * **Get Resume:** Not supported — `_get_resume_for_candidate_id` always returns `None` (Tracker RMS does not expose resume/attachment download for this integration path)

    Advanced candidate search with multiple criteria and pagination support.
  </Accordion>

  <Accordion title="Notes & Attachments">
    * Application Notes (Custom Implementation)
    * Candidate Notes (Custom Implementation)
    * Application Attachments (Custom Implementation)
    * Candidate Attachments (Custom Implementation)

    Write-path support for notes and attachments through Tracker's document API. Resume retrieval is not supported.
  </Accordion>

  <Accordion title="Custom Fields (All Supported)">
    * Application Custom Fields (Custom Implementation)
    * Candidate Custom Fields (Custom Implementation)
    * Job Custom Fields (Custom Implementation)

    Tracker has rich custom field support across all entities.
  </Accordion>
</AccordionGroup>

## Implementation Notes

### Timezone Handling

**Critical implementation detail:**\
Tracker API returns timestamps in local time (not UTC). The client automatically adjusts `updated_after` parameters by subtracting 8 hours to cover all US timezones and prevent data loss.

```python theme={null}
# Example: 2025-01-15T00:00:00Z becomes 2025-01-14T16:00:00Z
adjusted_dt = dt - timedelta(hours=8)
```

### Metadata Management

Tracker uses a metadata system (`TrackerMetaData`) that caches:

* Available job categories
* Application statuses
* Workflow configurations

Metadata is loaded once per client instance for performance.

### Library Architecture

Uses `TrackerAtsLibrary` for API communication with MW Resources API key configuration.

## Known Limitations

The following limitations apply:

* **Rejection Reason Enumeration:** No disposition list for the product (`supports_disposition_reasons = False`; `get_disposition_reasons()` returns `[]`).
* **Reject / Bulk Reject:** `reject_application` is not implemented; `bulk_reject_applications` is a stub. Use stage movement where a rejection stage is configured.
* **Resume download:** Candidate resume bytes are not fetched from Tracker (`_get_resume_for_candidate_id` returns `None`).
* **Local Time Handling:** Streaming filters adjust `updated_after` (subtract 8 hours) because Tracker returns local-time semantics; see `_adjust_datetime_for_timezone`.

## Related Files

* Implementation: `server/ats/tracker_ats/tracker_ats_client.py` (\~1,200 lines)
* Library: `server/ats/tracker_ats/tracker_library.py`
* Models: `server/ats/tracker_ats/tracker_models.py`
* Field Mappings: `server/ats/field_type_mapper.py` (TRACKER\_FIELD\_MAPPINGS)
* Base Class: `server/ats/base_ats_client.py`

## See Also

* [ATS Coverage Matrix](/internal/ats-coverage)
* [Tracker Workable Wrapper](/internal/ats/tracker-workable) - Hybrid client for MW Resources
