> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.vitablehealth.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.vitablehealth.com/_mcp/server.

# Employee Lifecycle

> How employees transition between statuses in the Vitable API and which webhook events signal each change.

Every employee in Vitable moves through a defined lifecycle from creation to termination. Understanding these transitions helps you keep your system in sync with Vitable and respond to changes as they happen. This guide covers the two API statuses, the webhook events that signal lifecycle changes, and how benefits eligibility fits in.

## Quick Reference

| Status     | Triggering Action                                                           | Webhook Events                                                    |
| ---------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `active`   | Census sync creates the employee                                            | `employee.eligibility_granted`, `employee.eligibility_terminated` |
| `inactive` | Employee is deactivated (e.g., omitted from census sync, admin termination) | `employee.deactivated`                                            |

Employees have a binary status — `active` or `inactive`. Eligibility is tracked separately from active status. An employee can be active but not yet eligible (e.g., waiting period in progress).

## Understanding Employee Statuses

The `GET /v1/employees/{id}` endpoint returns one of two values in the `status` field: `active` or `inactive`. There are no other API statuses.

```mermaid
sequenceDiagram
    participant P as Partner
    participant V as Vitable
    P->>V: Census sync creates employee
    Note over V: Status: active
    V--)P: webhook: employee.eligibility_granted
    Note over V: Employee may later lose eligibility
    V--)P: webhook: employee.eligibility_terminated
    Note over V: Employee removed from roster
    V--)P: webhook: employee.deactivated
    Note over V: Status: inactive
```

**Diagram summary:**

* An employee enters the `Active` state when created through a census sync.
* While `Active`, the employee may receive `employee.eligibility_granted` or `employee.eligibility_terminated` webhook events as their benefits eligibility changes.
* An employee transitions to `Inactive` when they are deactivated (e.g., omitted from a census sync, or terminated by an admin).
* The `employee.deactivated` webhook event fires to signal that the employee has been deactivated.

## Handling New Hires

When you submit employee data through `POST /v1/employers/{id}/census-sync`, Vitable creates employee records asynchronously. Each new employee starts with `status: "active"`.

```mermaid
sequenceDiagram
    participant P as Partner
    participant V as Vitable
    P->>V: POST /v1/employers/{id}/census-sync
    V-->>P: 202 Accepted
    Note over V: Employee created (status: active)
    Note over V: Benefits eligibility evaluated
    V--)P: webhook: employee.eligibility_granted
```

**Diagram summary:**

* Vitable creates the employee record with `status: "active"` after processing the census sync.
* Vitable evaluates the employee's benefits eligibility.
* When an employee becomes eligible, the `employee.eligibility_granted` event fires.

After the census sync completes, you can verify that employees were created by calling `GET /v1/employers/{id}/employees` and paginating through the results.

> **Tip**
>
> Benefits eligibility is not a field on the employee resource. It is signaled exclusively through webhook events. Listen for the `employee.eligibility_granted` event to know when an employee can enroll.

### Tracking Eligibility Events

Two webhook events track benefits eligibility changes:

* **`employee.eligibility_granted`** fires when an employee becomes eligible for benefits. Once you receive this event, the employee's enrollment window opens and they can select benefits.

* **`employee.eligibility_terminated`** fires when an employee's benefits eligibility is revoked, including as part of a termination flow. After this event, the employee can no longer enroll in new benefits.

You can fetch the employee's current data at any time with `GET /v1/employees/{id}` to check fields like `employee_class`, `hire_date`, and `termination_date`.

## Handling Terminations

When an employee is terminated, the `termination_date` field is set and the `status` changes to `inactive`. This triggers a cascade of events.

```mermaid
sequenceDiagram
    participant P as Partner
    participant V as Vitable
    Note over V: Employee is active
    Note over V: Termination date set
    V--)P: webhook: employee.eligibility_terminated
    V--)P: webhook: enrollment.terminated (per enrollment)
    V--)P: webhook: employee.deactivated
    Note over V: Status: inactive
```

**Diagram summary:**

* An `Active` employee transitions to `Inactive` when a termination date is set.
* The `employee.eligibility_terminated` event fires, signaling that the employee is no longer eligible for benefits.
* The `employee.deactivated` event fires after termination processing completes.
* For each active enrollment, an `enrollment.terminated` event fires as the enrollment transitions to `inactive`.

> **Warning**
>
> When an employee is deactivated, all of their active enrollments are also ended. Each enrollment transitions from `enrolled` to `inactive`, and you receive an `enrollment.terminated` webhook event for each one. Make sure your system handles these cascading events. See the [Enrollment Lifecycle](/embedded_benefits/concepts/enrollment-lifecycle) guide for details on enrollment status transitions.

### Understanding the Deactivation Event

The `employee.deactivated` event fires when an employee has been deactivated within Vitable — for example, when they are omitted from a census sync or terminated by an admin. When you fetch the employee after receiving this event, the response shows `status: "inactive"`.

Use this event as confirmation that deactivation processing on Vitable's side is complete. It is safe to perform any final cleanup in your system (archiving records, removing access, etc.) after receiving `employee.deactivated`.

## Troubleshooting

**Missing eligibility events.** If your webhook endpoint was down when `employee.eligibility_granted` fired, you may not know that an employee is eligible for benefits. Use `GET /v1/webhook-events` to query for missed events within a timeframe, and `GET /v1/webhook-events/{event_id}/deliveries` to check delivery status.

**Unexpected deactivation cascades.** A single employee deactivation produces multiple webhook events: `employee.eligibility_terminated`, `employee.deactivated`, and one `enrollment.terminated` per active enrollment. If your handler processes these independently, make sure it handles them idempotently. Use the `event_id` to deduplicate.

> **Tip**
>
> You can always fetch the current state of any employee with `GET /v1/employees/{id}`. After receiving a webhook event, use the `resource_id` from the payload to retrieve fresh data rather than relying on cached state.

## Related Webhooks

| Event                             | Description                                                                                                                   |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `employee.eligibility_granted`    | An employee has become eligible for benefits. [Learn more](/webhooks/events)                                                  |
| `employee.eligibility_terminated` | An employee's benefits eligibility has been revoked. [Learn more](/webhooks/events)                                           |
| `employee.deactivated`            | An employee has been deactivated (e.g., omitted from census sync, admin termination). [Learn more](/webhooks/events)          |
| `enrollment.terminated`           | An enrollment has been ended (enrollment moves to `inactive`). [Learn more](/embedded_benefits/concepts/enrollment-lifecycle) |

## Related API Endpoints

* [`GET /v1/employees/{id}`](/api/employees/get) — Retrieve an employee's current data, including `status`, `hire_date`, and `employee_class`.
* [`GET /v1/employers/{id}/employees`](/api/employers/list-employees) — List all employees for an employer. Supports pagination with `page` and `limit` query parameters.
* [`GET /v1/webhook-events`](/api/webhook-events/list) — Query webhook events to recover missed events or audit delivery history.
* [`GET /v1/webhook-events/{event_id}/deliveries`](/api/webhook-events/list-deliveries) — Check delivery attempts for a specific webhook event.