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

# Sync Dependents and Beneficiaries

> Build an accurate picture of who is covered under each employee, not just who is recorded as a dependent.

## What you'll use

**Models** - employee, dependent, dependent benefit, benefit, employer benefit
**Events** - `connector_data_modified`, `connector_synced`

<Info>
  **Before you start**

  * The customer's benefits module is in scope, and `date_of_birth` is available - it is commonly gated behind a separate sensitive-data permission.
</Info>

## Steps

<Steps>
  <Step title="Read who is recorded as a dependent">
    ```bash theme={null}
    curl --request GET \
      --url 'https://api.bindbee.dev/api/hris/v1/dependents?employee_id=<EMPLOYEE_ID>&page_size=200' \
      --header 'Authorization: Bearer <BINDBEE_API_KEY>' \
      --header 'X-Connector-Token: <CONNECTOR_TOKEN>'
    ```

    Use this for demographics only - name, date of birth, relationship. It tells you nothing about coverage.

    **Result:** The people on file under this employee.
  </Step>

  <Step title="Read who is actually covered">
    ```bash theme={null}
    curl --request GET \
      --url 'https://api.bindbee.dev/api/hris/v1/dependent-benefits?page_size=200' \
      --header 'Authorization: Bearer <BINDBEE_API_KEY>' \
      --header 'X-Connector-Token: <CONNECTOR_TOKEN>'
    ```

    Build the covered-lives list from this collection and join back to dependents for their details - never the other way round.

    ```python theme={null}
    covered = {db["dependent"] for db in dependent_benefits}
    lives = [d for d in dependents if d["id"] in covered]   # not: lives = dependents
    ```

    **Result:** Coverage, as distinct from existence.
  </Step>

  <Step title="Page both collections fully">
    Both are paginated. A partial walk understates coverage, which is the direction that causes problems.

    Follow the cursor until it stops coming back, and don't stop on a short page - see [Pagination](/api-reference/basics/pagination).

    **Result:** Complete sets, not first pages.
  </Step>

  <Step title="Cross-check against the coverage tier">
    An employee on a family tier with no dependent records is a data-quality signal worth surfacing.

    ```bash theme={null}
    curl --request GET \
      --url 'https://api.bindbee.dev/api/hris/v1/benefits?employee_id=<EMPLOYEE_ID>&page_size=200' \
      --header 'Authorization: Bearer <BINDBEE_API_KEY>' \
      --header 'X-Connector-Token: <CONNECTOR_TOKEN>'
    ```

    Compare `coverage_tier` on the enrollment against the number of covered dependents you found. Report the mismatch rather than reconciling it silently - the discrepancy is usually real and belongs with the customer.

    **Result:** Disagreements surfaced instead of averaged away.
  </Step>

  <Step title="Map attributes the model doesn't carry">
    Beneficiary designations, allocation percentages, and relationship detail are frequently in the raw payload but not unified.

    Find the path with the raw-data endpoint, then map it - see [Inspect raw data](/guides/reading-writing/raw-data). Read the results with `include_custom_fields=true`.

    **Result:** The attributes your file format needs.
  </Step>

  <Step title="Subscribe to changes on both models">
    Subscribe to `connector_data_modified`, not just `employee_data_changed` - dependent changes may surface under either.

    Re-read dependents and dependent benefits whenever the employee changes. `modified_after` is per model, so an employee changing does not mark their dependents as changed - see [modified\_after](/guides/reading-writing/reading-data/modified-after).

    **Result:** Coverage that stays current as families change.
  </Step>
</Steps>

## Constraints specific to this combination

**Existence is not coverage.** A dependent record means the employee has recorded that person. A dependent benefit means they're enrolled in a specific plan. Employees commonly record dependents who are covered under a spouse's plan, or who were dropped at a prior enrollment. Build coverage from dependent benefits and use dependents only for demographics - counting dependents as covered lives is the standard cause of an eligibility file with too many people on it.

**Dependents and beneficiaries are different concepts.** A dependent is covered under a health plan; a beneficiary receives a life or retirement benefit and is often neither covered nor a dependent. Most HRIS platforms model them separately or conflate them inconsistently. Check `raw_data` to see how the specific platform distinguishes them before assuming the dependent model covers both.

**Coverage tier and dependent records disagree more often than they should.** An employee on an employee-plus-family tier with no dependent records is common - the tier was elected in benefits administration while dependent details live elsewhere, or were never entered. Treat a mismatch as a data-quality signal to surface, not as something to reconcile silently.

**Relationship vocabularies are customer-specific.** Spouse, domestic partner, child, stepchild, and legal ward vary in naming and availability across platforms and customer configurations. Map them per connector rather than assuming a standard set.

**Dependent changes fire under the parent employee.** A dependent added or removed may surface as a change on the employee rather than on the dependent model. Subscribe to data model change rather than employee model change alone, and re-read dependents whenever the employee changes - see [modified\_after](/guides/reading-writing/reading-data/modified-after) for why the filter alone won't catch related-model changes.

## Frequently Asked Questions

<AccordionGroup>
  <Accordion title="The eligibility file has too many lives on it">
    Dependents were counted as covered. Build the list from dependent benefits.
  </Accordion>

  <Accordion title="Dependents exist but no dependent benefits">
    Either they genuinely aren't enrolled, or the integration doesn't expose dependent coverage. Check `raw_data` on someone you know is covered - see [Inspect raw data](/guides/reading-writing/raw-data).
  </Accordion>

  <Accordion title="date_of_birth is null for every dependent">
    A sensitive-data permission rather than absence. See [Origin-system errors](/guides/troubleshooting/errors#origin-system-errors).
  </Accordion>

  <Accordion title="A dependent was added but nothing fired">
    The change may have surfaced on the employee rather than the dependent. Re-read dependents whenever the employee changes.
  </Accordion>
</AccordionGroup>

## Related

* [Reading benefits](/guides/data-models/benefits)
* [Get Dependents](/hris/dependents/get-dependents) · [Get Dependent Benefits](/hris/dependent-benefits/get-dependent-benefits)
* [Sync Census Data for Quoting](/get-started/use-cases/sync-census-data)
