Inviting an Employee

This guide walks you through the POST /employees/invite endpoint — how to invite employees, contractors, and admins to a company through the Friday API. You'll learn which fields are required for each employment type, how plan tiers affect validation, and how to handle common edge cases.

Prerequisites

  • You have an API key for the company. See Getting API Access.
  • You know the company's plan tier (timetracking, payroll, or premium), as it determines which employment types and fields are available.
  • If inviting a payroll employee, you know the workplace ID. You can look up available workplaces with GET /workplaces.

The Basics

Every invite request requires five fields, regardless of plan or employment type:

{
  "first_name": "Jane",
  "last_name": "Smith",
  "email": "[email protected]",
  "employment_type": "employee",
  "start_date": "2026-04-01T00:00:00.000Z"
}
FieldTypeDescription
first_namestringFirst name.
last_namestringLast name.
emailstringEmail address (must be lowercase). This is used to create the employee's account.
employment_typestringOne of "admin", "employee", or "contractor".
start_datedate-timeThe employee's start date.

Beyond these, which additional fields are accepted (or required) depends on the plan tier and employment type.


Plan Tiers and What They Accept

Timetracking plan

Timetracking plans support admin and employee employment types only. Contractors are not available.

On a timetracking plan, you send just the five core fields plus optional middle_name and department_id. No payroll-specific fields are accepted — the API will reject them with a 400 error.

No timetrack_only flag — On timetracking plans, timetrack_only is not accepted in the request. All employees on a timetracking plan are inherently time-track-only because payroll is not available on this plan.

Payroll plan

Payroll plans support all three employment types: admin, employee, and contractor. You can also send payroll-specific fields like wage information, workplace, and the timetrack_only flag.

Premium plan

Premium plans have everything payroll plans have, plus manager_type for admin employees.


Employment Type Field Matrix

This table shows every field, whether it's required/optional/not accepted for each employment type, and any plan conditions.

Always required (all types, all plans)

FieldNotes
first_name
last_name
emailMust be lowercase
employment_type"admin", "employee", or "contractor"
start_dateISO 8601 date-time

Always optional (all types, all plans)

FieldNotes
middle_nameMiddle name or initial
department_idInteger ID of an existing department in the company

Admin fields

FieldRequired?Notes
manager_typeOptionalPremium plans only. One of: "admin_manager", "payroll_manager", "timesheet_manager". Rejected on timetracking/payroll plans.

Admins have the simplest invite payload. They don't take wage fields, workplace, SSN, or timetrack_only.

Employee fields (payroll/premium plans)

FieldRequired?Condition
timetrack_onlyOptionalDefaults to false. When true, skips all payroll fields. Not accepted on timetracking plans.
workplaceRequiredWhen timetrack_only is false. This is the workplace ID from GET /workplaces.
payment_unitRequiredWhen timetrack_only is false. One of: "hour", "salary", "hourly_salary".
payment_amountRequiredWhen payment_unit includes "hour". Hourly rate.
overtime_amountRequiredWhen payment_unit includes "hour". Overtime rate.
salaryRequiredWhen payment_unit includes "salary". Salary amount. Max: 999,999,999.
salary_typeRequiredWhen payment_unit includes "salary". One of: "yearly", "quarterly", "monthly", "semimonthly", "weekly", "biweekly".
default_hoursOptionalDefault weekly hours (0–168).
pto_payment_amountOptionalHourly rate for PTO payouts.
daily_time_limitOptionalDaily time limit in hours.
weekly_time_limitOptionalWeekly time limit in hours.
paid_lunch_timeOptionalPaid lunch time in minutes.
is_i9_form_requiredOptionalWhether the employee needs I-9 verification.
ssnOptionalSocial Security Number (9 digits, no dashes).
working_stateOptionalTwo-letter state code for the employee's working state.

Employee fields (timetracking plan)

On a timetracking plan, none of the payroll fields above are accepted. You send only the core fields plus middle_name and department_id.

Contractor fields (payroll/premium plans only)

FieldRequired?Condition
timetrack_onlyOptionalDefaults to false. When true, skips all payroll fields.
typeOptionalContractor entity type (e.g. "individual", "business").
einOptionalEmployer Identification Number for business contractors.
business_nameOptionalBusiness name for business contractors.
payment_unitConditionalSame wage branching logic as employees (required when timetrack_only is false).
payment_amountConditionalSame as employees.
overtime_amountConditionalSame as employees.
salaryConditionalSame as employees.
salary_typeConditionalSame as employees.
default_hoursOptionalSame as employees.
pto_payment_amountOptionalSame as employees.
daily_time_limitOptionalSame as employees.
weekly_time_limitOptionalSame as employees.
paid_lunch_timeOptionalSame as employees.
ssnOptionalSocial Security Number.
working_stateOptionalWorking state.

No workplace required — Unlike employees, contractors don't require a workplace value.

Contractors are not available on timetracking plans. Attempting to invite a contractor on a timetracking plan returns a 400 error.


Wage Branching Logic

When timetrack_only is false (the default) and the employment type is employee or contractor on a payroll/premium plan, you must specify how the person is paid.

The payment_unit field determines which additional wage fields are required:

Hourly (payment_unit: "hour")

{
  "payment_unit": "hour",
  "payment_amount": 32.50,
  "overtime_amount": 1.5
}
FieldRequired?
payment_amountYes — the hourly rate (0 is allowed)
overtime_amountYes — the overtime rate
default_hoursOptional

Salary (payment_unit: "salary")

{
  "payment_unit": "salary",
  "salary": 85000,
  "salary_type": "yearly"
}
FieldRequired?
salaryYes — the salary amount (0 is allowed)
salary_typeYes — the period the salary represents

Hourly + Salary (payment_unit: "hourly_salary")

This hybrid type requires both the hourly and salary fields:

{
  "payment_unit": "hourly_salary",
  "payment_amount": 25.00,
  "overtime_amount": 1.5,
  "salary": 52000,
  "salary_type": "yearly"
}

Full Examples by Scenario

Timetracking plan — Admin

The simplest possible invite. Just the core fields:

POST /employees/invite

{
  "first_name": "John",
  "last_name": "Doe",
  "email": "[email protected]",
  "employment_type": "admin",
  "start_date": "2026-04-01T00:00:00.000Z"
}

Timetracking plan — Employee

Identical structure. No payroll fields, no timetrack_only:

POST /employees/invite

{
  "first_name": "Jane",
  "last_name": "Smith",
  "email": "[email protected]",
  "employment_type": "employee",
  "start_date": "2026-04-01T00:00:00.000Z"
}

Payroll plan — Hourly employee

Includes workplace and hourly wage fields:

POST /employees/invite

{
  "first_name": "Alex",
  "last_name": "Johnson",
  "email": "[email protected]",
  "employment_type": "employee",
  "start_date": "2026-04-01T00:00:00.000Z",
  "workplace": "wrk_abc123",
  "payment_unit": "hour",
  "payment_amount": 32.50,
  "overtime_amount": 1.5,
  "default_hours": 40,
  "department_id": 5
}

Payroll plan — Salaried employee

POST /employees/invite

{
  "first_name": "Morgan",
  "last_name": "Lee",
  "email": "[email protected]",
  "employment_type": "employee",
  "start_date": "2026-04-01T00:00:00.000Z",
  "workplace": "wrk_abc123",
  "payment_unit": "salary",
  "salary": 85000,
  "salary_type": "yearly"
}

Payroll plan — Timetrack-only employee

When timetrack_only is true, no wage or workplace fields are needed:

POST /employees/invite

{
  "first_name": "Pat",
  "last_name": "Taylor",
  "email": "[email protected]",
  "employment_type": "employee",
  "timetrack_only": true,
  "start_date": "2026-04-01T00:00:00.000Z"
}

Payroll plan — Contractor

Contractors don't require a workplace. Include contractor-specific fields like type and business_name:

POST /employees/invite

{
  "first_name": "Chris",
  "last_name": "Miller",
  "email": "[email protected]",
  "employment_type": "contractor",
  "start_date": "2026-04-01T00:00:00.000Z",
  "type": "business",
  "business_name": "Miller Consulting LLC",
  "ein": "123456789",
  "payment_unit": "hour",
  "payment_amount": 75.00,
  "overtime_amount": 1.5
}

Premium plan — Admin with manager type

POST /employees/invite

{
  "first_name": "Sam",
  "last_name": "Lee",
  "email": "[email protected]",
  "employment_type": "admin",
  "start_date": "2026-04-01T00:00:00.000Z",
  "manager_type": "payroll_manager"
}

The Response

A successful invite returns 201 Created with a summary of the new employee record:

{
  "data": {
    "employee_id": 123,
    "first_name": "Alex",
    "middle_name": null,
    "last_name": "Johnson",
    "email": "[email protected]",
    "employment_type": "employee",
    "timetrack_only": false,
    "is_active": false,
    "onboarding_status": "blocking",
    "status": null,
    "start_date": "2026-04-01T00:00:00.000Z"
  }
}

Note that newly invited employees:

  • Start with is_active: false — they become active after completing onboarding.
  • Start with onboarding_status: "blocking" — the employee needs to complete their onboarding steps.
  • Have status: null until their status is set through the onboarding process.

Use GET /employees/:employee_id to fetch the full employee detail once the record is created.


Inviting the Same Person Twice

A single person (identified by email) can hold multiple employment types at the same company. For example, you might invite [email protected] as both an admin and an employee. Each invite creates a separate employee record with its own employee_id.

However, you cannot invite the same email with the same employment type twice. If you try, the API returns:

{
  "error": "Employee already exists"
}

This applies per employment type. If [email protected] already has an employee record, inviting her again as employee fails — but inviting her as admin succeeds and creates a second record.


Common Pitfalls

  • Sending payroll fields on a timetracking plan — The API strictly rejects payroll-specific fields (workplace, payment_unit, salary, etc.) when the company is on a timetracking plan. If you get a 400 error about payroll fields, check the company's plan with GET /companies.

  • Missing wage fields — When timetrack_only is false on a payroll/premium plan, the payment_unit field is required for employees. Forgetting it (or forgetting the dependent fields like payment_amount for hourly workers) results in a 400.

  • Setting timetrack_only on an admin — The timetrack_only flag is not valid for admin employment types. Admins are never included in payroll by definition, so the flag has no meaning. The API returns a 400 if you try.

  • Setting manager_type on a non-premium plan — Manager types are exclusive to premium plans. Sending manager_type on a timetracking or payroll plan returns a 400.

  • Setting manager_type on a non-admin — Only admin employment types accept manager_type. Sending it for an employee or contractor returns a 400.

  • Forgetting the workplace — On payroll/premium plans, employees (when timetrack_only is false) require a workplace value. Contractors do not. If you're not sure which workplaces are available, call GET /workplaces first.

  • Email case sensitivity — The email field must be lowercase. The API enforces this — if you send mixed case, it will be normalized, but it's best to send lowercase from the start.

  • Duplicate invites — The API checks for existing records with the same email and employment type at the same company. If a match is found, you'll get a 400. This does not prevent inviting the same email under a different employment type.


Quick Reference

Scenarioemployment_typetimetrack_onlyKey required fields
Timetracking adminadminCore fields only
Timetracking employeeemployeeCore fields only
Payroll adminadminCore fields only
Payroll employee (full)employeefalseCore + workplace + payment_unit + wage fields
Payroll employee (TT only)employeetrueCore fields only
Payroll contractorcontractorfalseCore + payment_unit + wage fields
Payroll contractor (TT only)contractortrueCore fields only
Premium admin w/ manageradminCore + manager_type

What's Next

  • Understand the employee object — See The Employee Object guide for a full field reference and explanation of employment types, timetrack-only, and earnings.
  • Update employees — Use PATCH /employees/:employee_id to modify profile fields, addresses, departments, and workplaces after creation.
  • Set up webhooks — Subscribe to employee.created events to be notified when employees are added (whether through the API or the Friday dashboard). See the Webhooks guide.