Syncing Benefit and Retirement Deductions
Keep each worker's deductions in Everee matching the elections in your benefits or retirement platform, and reconcile what payroll took.
If you administer benefits or retirement plans, you hold the source of truth for what each participant has elected. Everee holds the payroll that deducts it. This guide shows how to keep the two in step with no one entering anything by hand, and how to confirm after every payroll that the amounts match.
The workflow has four parts: match your participants to Everee workers, apply their deductions, keep them current as elections change, and reconcile after each payroll.
1. Match participants to workers
Every deduction request identifies a worker, so first link each participant to an Everee worker. You can use your own worker ID or Everee's.
- List workers, or search by name or other term, to find them.
- Store the Everee
workerIdagainst your participant record, or store your own ID on the worker as its external worker ID. Then either one works in later requests. - Use a worker's hiring status if you need to know whether a person already has a payroll profile.
- Subscribe to
worker.createdandworker.profile-updatedso new hires and changes reach your system. See Onboarding and managing workers.
2. Apply deductions
There are three endpoints, one per kind of deduction. They work the same way and differ in which pay codes and amount options they take.
| Endpoint | Use it for |
|---|---|
| Apply benefit deduction | Medical, dental, vision, HSA, FSA, life, disability, and similar |
| Apply retirement deduction | 401(k), Roth 401(k), 403(b), IRAs, and state retirement plans |
| Apply other deduction | Dues, savings, and loan repayments |
You identify a deduction by the worker and the pay code, so you never store an Everee deduction ID. Other deductions also need your own externalId, because a worker can have several of the same type.
POST https://api.everee.com/integration/v1/deductions/benefits
{
"workerId": "emp-1042",
"payCode": "MEDICAL_INSURANCE",
"deductionAmount": {
"employeeAmount": { "amount": "150.00", "currency": "USD" },
"employerAmount": { "amount": "400.00", "currency": "USD" },
"periodType": "MONTHLY"
},
"effectiveDate": "2027-01-01"
}POST https://api.everee.com/integration/v1/deductions/retirement
{
"workerId": "emp-1042",
"payCode": "ERISA_401K",
"deductionPercentage": { "employeePercentage": 0.05 },
"employerMatchTiers": [
{ "matchRate": 1.0, "percentOfWages": 0.03 },
{ "matchRate": 0.5, "percentOfWages": 0.02 }
],
"effectiveDate": "2027-01-01"
}Points that cause the most trouble:
- Percentages are decimal fractions. Send
0.05for 5%, never5. - Send exactly one of
deductionAmountordeductionPercentage. Which one a pay code accepts is listed in the Deductions guide. - Fixed amounts are per period. Send the
periodTypethey apply to. Everee converts a monthly amount for companies that deduct monthly. - The retirement endpoint describes the employer match with
employerMatchTiers, not a single employer amount. - For an HSA, send
hsaLimitTypeasINDIVIDUALorFAMILY. - State retirement plan Roth 401(k)s need a state prefix, such as
CA_STATE_RETIREMENT_PLAN_ROTH_401K. - Custom pay codes work too. Use the
apiKeyof a pay code your company has set up for the same type of deduction.
Wage garnishments aren't set up through the API. They're entered in the Everee admin portal.
3. Keep deductions current
Each endpoint is one POST that creates, changes, or ends a deduction, depending on which dates you send.
| You send | What happens |
|---|---|
effectiveDate | The deduction is created, or updated if it already exists |
effectiveDate and effectiveEndDate | The same, with an end date |
Only effectiveEndDate | The existing deduction is ended |
That makes a sync simple. For each change in your system, send the request that describes the new state. You don't need to check what's already in Everee first.
Changing an election. Send the new amount with the date it takes effect. If the old deduction has never been used in a finalized payroll, it's updated in place. If it has, Everee ends it the day before your date and starts a new one on it, so past payrolls never change.
Ending an election. Send only effectiveEndDate. An unused deduction is removed entirely. A used one ends on the date you gave, or the earliest date that's still editable. Ending a deduction that doesn't exist, or already ended, returns 404.
Dates can move. A start date can't be earlier than the worker's earliest editable date. If it is, Everee moves it forward. The response always contains the dates that were actually used, so store those.
Errors to handle:
| Status | Meaning |
|---|---|
400 | The end date is before the start date |
404 | The pay code isn't valid for that endpoint, or you tried to end a deduction that doesn't exist |
422 | Neither date was sent, the amount options don't fit the pay code, or a required field is missing |
4. Reconcile after each payroll
The apply endpoints say what should be deducted. Get deduction reconciliation tells you what payroll did deduct and what the employer contributed. Use it to tie out to your records, and to know how much to remit.
GET https://api.everee.com/integration/v1/deductions/reconciliation?pay-period-start-date=2026-10-05&pay-period-end-date=2026-10-11&category=RETIREMENT- Whole pay periods only. The dates must match a pay period exactly, or no rows are returned.
- Wait until payroll has finished processing, then page through in one pass with the cursor.
- Each row is one payment and pay code. It carries
amountDeducted,employerAmountContributed, and year-to-date totals for both. Retirement plans also get the payment's taxable wages and hours worked, which every row of a payment repeats, so take them from one row and don't add them up. remittedByEvereetells you whether Everee funds and remits the amounts. If it'strue, don't fund them again.- Filter by
category(BENEFIT,OTHER, orRETIREMENT) or bypay-code.
Pulled-back payments and reversals
A payment can be pulled back after it was paid. Its rows stay, with status of PULLED_BACK instead of PAID. Count only PAID rows for what stands, and use the PULLED_BACK rows to reverse anything you already funded or credited. If payroll then runs again, the worker has two payments in that period, one of each.
A reversed deduction appears as a negative amountDeducted, in the period of the payment that carried it. To find what a worker has had deducted overall, add up their rows.
Match what you expected
For each participant, compare what you expected to what you got:
for each row in reconciliation(pay period):
if row.status == PAID:
actual[worker, payCode] += row.amountDeducted
for each participant election:
expected = election amount for the period
if actual != expected: investigateCommon reasons for a difference:
- The election's
effectiveDatewas moved forward to the worker's earliest editable date. - A cap you set, such as a lifetime limit, was reached.
- A change mid-period: the old deduction ended the day before the new one started.
- A payment was pulled back and rerun, or a deduction was reversed.
Remember to tolerate new payCode, type, and status values, because new ones may be added.
Putting it together
A typical sync for a benefits platform:
- Open enrollment closes. For each participant, apply their elections with an
effectiveDateof the plan year start. - Mid-year change. A qualifying life event changes an election. Send the new amount with its effective date.
- Termination. A worker leaves. Send only an
effectiveEndDatefor each of their deductions. See Onboarding and managing workers. - After each payroll. Pull the reconciliation for the pay period, compare it to your records, and remit.
Next steps
Updated about 2 hours ago