Summary and recommendation
Paylocity exposes a REST API (base URL: https://api.paylocity.com/api/v2) authenticated via OAuth 2.0 Client Credentials. The single required scope is WebLinkAPI, obtained by POSTing to https://api.paylocity.com/IdentityServer/connect/token - note this token endpoint is separate from the API base URL. All endpoint paths require a companyId, which is a Paylocity-assigned company code, not a UUID.
Date fields use MM/DD/YYYY throughout, not ISO 8601. No official SDK is published; all integrations use raw HTTP. When building an identity graph from Paylocity data, the supervisorId, departmentCode, locationCode, and statusCode fields on the employee object are the primary signals for constructing and maintaining organizational hierarchy and access state.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 Client Credentials |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise (requires SSO add-on; estimated $22–32/employee/month full subscription) |
Authentication
Auth method: OAuth 2.0 Client Credentials
Setup steps
- Log in to Paylocity as an administrator and navigate to Settings > API Management.
- Create an API client application to obtain a Client ID and Client Secret.
- POST to https://api.paylocity.com/IdentityServer/connect/token with grant_type=client_credentials, client_id, client_secret, and scope=WebLinkAPI.
- Include the returned Bearer token in the Authorization header for all subsequent API requests.
- Tokens expire; implement token refresh logic using the same client credentials flow.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| WebLinkAPI | Primary scope granting access to Paylocity Web Services API endpoints including employee data. | All API operations (employee read/write, payroll, etc.) |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| employeeId | string | Unique identifier for the employee within the company. | required | required (path param) | Alphanumeric, assigned by employer or auto-generated. |
| companyId | string | Paylocity company code associated with the employee. | required | required (path param) | Provided by Paylocity during account setup. |
| firstName | string | Employee's legal first name. | required | optional | Max 40 characters. |
| lastName | string | Employee's legal last name. | required | optional | Max 40 characters. |
| workEmail | string | Primary work email address. | optional | optional | Used for SSO/SCIM identity matching. |
| homeEmail | string | Personal/home email address. | optional | optional | |
| hireDate | string (date) | Employee hire date in MM/DD/YYYY format. | required | optional | Format must match MM/DD/YYYY exactly. |
| statusCode | string | Employment status (e.g., A=Active, T=Terminated). | optional | optional | Termination requires separate termination endpoint. |
| departmentCode | string | Department code the employee belongs to. | optional | optional | Must match a valid department configured in Paylocity. |
| jobTitle | string | Employee's job title. | optional | optional | Max 50 characters. |
| supervisorId | string | Employee ID of the direct supervisor. | optional | optional | Must reference a valid existing employeeId. |
| locationCode | string | Work location code. | optional | optional | Must match a valid location in Paylocity. |
| payType | string | Pay type (e.g., Salary, Hourly). | required | optional | |
| salary | number | Annual salary amount. | optional | optional | Applicable when payType is Salary. |
| primaryPayRate | number | Hourly pay rate. | optional | optional | Applicable when payType is Hourly. |
| ssn | string | Social Security Number (masked in responses). | optional | optional | Returned masked (e.g., ***-**-1234) in GET responses. |
| birthDate | string (date) | Date of birth in MM/DD/YYYY format. | optional | optional | |
| gender | string | Gender code (M/F/U). | optional | optional | |
| ethnicity | string | Ethnicity code per EEO classifications. | optional | optional | |
| customFields | object | Company-defined custom fields (category1–category6, text1–text10, etc.). | optional | optional | Field names vary by company configuration. |
Core endpoints
Get Employee
- Method: GET
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees/{employeeId} - Watch out for: SSN and sensitive fields are masked in responses regardless of scope.
Request example
GET /api/v2/companies/12345/employees/E001
Authorization: Bearer {token}
Response example
{
"employeeId": "E001",
"firstName": "Jane",
"lastName": "Doe",
"workEmail": "jane.doe@example.com",
"statusCode": "A"
}
Get All Employees
- Method: GET
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees - Watch out for: Returns all active and inactive employees. Filter by statusCode client-side; no server-side status filter parameter is documented.
Request example
GET /api/v2/companies/12345/employees?pagesize=100&pagenumber=1
Authorization: Bearer {token}
Response example
[
{"employeeId": "E001", "firstName": "Jane", ...},
{"employeeId": "E002", "firstName": "John", ...}
]
Create Employee
- Method: POST
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees - Watch out for: Response only returns the new employeeId. Perform a subsequent GET to retrieve the full employee object.
Request example
POST /api/v2/companies/12345/employees
Content-Type: application/json
{
"firstName": "Jane",
"lastName": "Doe",
"hireDate": "01/15/2024",
"payType": "Salary"
}
Response example
{
"employeeId": "E099"
}
Update Employee
- Method: PATCH
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees/{employeeId} - Watch out for: PATCH is partial update. Omitted fields are not cleared. Some fields (e.g., pay changes) may require effective dating via separate sub-resource endpoints.
Request example
PATCH /api/v2/companies/12345/employees/E001
Content-Type: application/json
{
"jobTitle": "Senior Engineer",
"departmentCode": "ENG"
}
Response example
HTTP 200 OK
{}
Get Employee Custom Fields
- Method: GET
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees/{employeeId}/customfields - Watch out for: Custom field names and categories are company-specific; schema must be retrieved from Paylocity admin configuration.
Request example
GET /api/v2/companies/12345/employees/E001/customfields
Authorization: Bearer {token}
Response example
[
{"category": "category1", "label": "Badge ID", "value": "B-4421"}
]
Get Changed Employees
- Method: GET
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees/changed - Watch out for: Returns only employeeIds of changed records, not full objects. Requires subsequent GET per employee to retrieve updated data.
Request example
GET /api/v2/companies/12345/employees/changed?fromDate=2024-01-01
Authorization: Bearer {token}
Response example
[
{"employeeId": "E001"},
{"employeeId": "E045"}
]
Add/Update Employee Pay
- Method: PUT
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/employees/{employeeId}/pay - Watch out for: Pay changes require an effectiveDate. Future-dated changes are queued and applied on that date.
Request example
PUT /api/v2/companies/12345/employees/E001/pay
Content-Type: application/json
{
"salary": 95000,
"effectiveDate": "02/01/2024"
}
Response example
HTTP 200 OK
{}
Get Company Codes (Departments, Locations)
- Method: GET
- URL:
https://api.paylocity.com/api/v2/companies/{companyId}/codes/{codeResource} - Watch out for: Must call this endpoint to validate departmentCode, locationCode, and other coded fields before creating/updating employees to avoid validation errors.
Request example
GET /api/v2/companies/12345/codes/department
Authorization: Bearer {token}
Response example
[
{"code": "ENG", "description": "Engineering"},
{"code": "HR", "description": "Human Resources"}
]
Rate limits, pagination, and events
- Rate limits: Paylocity does not publicly document specific rate limit tiers. Practical limits are enforced server-side; excessive requests result in HTTP 429 responses.
- Rate-limit headers: Unknown
- Retry-After header: Unknown
- Rate-limit notes: No official rate limit documentation found. Paylocity recommends contacting their integration support team for throughput guidance. Implement exponential backoff on 429 responses.
- Pagination method: offset
- Default page size: 25
- Max page size: 100
- Pagination pointer: pagesize / pagenumber
| Plan | Limit | Concurrent |
|---|---|---|
| Standard API Access | Not publicly documented | 0 |
- Webhooks available: No
- Webhook notes: Paylocity does not offer outbound webhooks via the public Web Services API. Event-driven integration requires polling the /employees/changed endpoint.
- Alternative event strategy: Poll GET /companies/{companyId}/employees/changed on a schedule to detect new or modified employee records.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise (requires SSO add-on; estimated $22–32/employee/month full subscription)
Endpoint: Provided by Paylocity upon SSO/SCIM enablement (tenant-specific URL configured in IdP)
Supported operations: Create User (POST /Users), Read User (GET /Users/{id}), Update User (PUT/PATCH /Users/{id}), Deactivate User (PATCH /Users/{id} active=false), List Users (GET /Users)
Limitations:
- SSO must be configured and active before SCIM provisioning can be enabled.
- SCIM is enabled via HR & Payroll > User Access > SSO Configuration > SCIM Provisioning in the Paylocity admin UI.
- Supported IdPs include Okta, Microsoft Entra ID (Azure AD), and OneLogin; Google Workspace is not officially supported.
- SCIM provisions Paylocity portal user access, not full employee HR records; use the REST API for HR data management.
- Group provisioning support is limited; verify with Paylocity support for current Group endpoint availability.
- SCIM bearer token is generated within Paylocity admin and must be manually rotated.
Common scenarios
Three integration patterns cover the majority of use cases. First, employee onboarding via REST: POST to /employees returns only the new employeeId - a follow-up GET is required to confirm the full record, and pay data requires a separate PUT to /employees/{employeeId}/pay with an explicit effectiveDate.
Second, change-sync to downstream systems: Paylocity has no outbound webhooks. poll GET /employees/changed to retrieve a list of modified employeeIds, then issue individual GET calls per ID - this N+1 pattern must be accounted for in throughput planning given undocumented rate limits (HTTP 429 is the only signal.
implement exponential backoff). Third, SCIM provisioning from an IdP (Okta, Entra ID, OneLogin): SCIM manages portal login access only - it does not write HR or payroll records.
New hire HR data still requires REST API calls or manual entry regardless of SCIM being active. The SCIM bearer token is generated in Paylocity admin and must be manually rotated in both Paylocity and the IdP when it expires.
Onboard a new employee via REST API
- Authenticate: POST to token endpoint with client_credentials to obtain Bearer token.
- Retrieve valid codes: GET /companies/{companyId}/codes/department and /codes/location to validate departmentCode and locationCode values.
- Create employee: POST /companies/{companyId}/employees with required fields (firstName, lastName, hireDate, payType).
- Capture returned employeeId from response.
- Set pay: PUT /companies/{companyId}/employees/{employeeId}/pay with salary/rate and effectiveDate.
- Verify: GET /companies/{companyId}/employees/{employeeId} to confirm full record.
Watch out for: POST /employees only returns employeeId; the full record is not returned in the creation response. Pay changes require a separate PUT call with an effectiveDate.
Sync employee changes to downstream systems
- Authenticate with client_credentials to obtain Bearer token.
- Poll GET /companies/{companyId}/employees/changed?fromDate={lastSyncDate} to retrieve list of changed employeeIds.
- For each returned employeeId, call GET /companies/{companyId}/employees/{employeeId} to fetch updated record.
- Map Paylocity fields to downstream system schema and push updates.
- Store current timestamp as lastSyncDate for next polling cycle.
Watch out for: No webhooks are available; polling frequency must be balanced against undocumented rate limits. The changed endpoint returns IDs only, requiring N+1 GET calls.
Enable SCIM provisioning from Okta
- Confirm Paylocity Enterprise plan with SSO add-on is active.
- In Paylocity admin: navigate to HR & Payroll > User Access > SSO Configuration and enable SSO with Okta.
- Enable SCIM Provisioning within the same SSO Configuration screen; copy the SCIM base URL and generate a bearer token.
- In Okta Admin Console: add Paylocity app, navigate to Provisioning tab, enter SCIM base URL and bearer token.
- Enable provisioning features: Create Users, Update User Attributes, Deactivate Users.
- Test with a single user assignment before enabling group-based provisioning.
Watch out for: SCIM provisions Paylocity portal login access only, not full HR employee records. New hires still require REST API or manual entry for HR/payroll data. The SCIM bearer token must be manually rotated in both Paylocity and Okta when it expires.
Why building this yourself is a trap
Several sharp edges compound integration risk. Coded fields (departmentCode, locationCode, jobCode) must exactly match values in Paylocity company configuration; invalid codes return validation errors with no fuzzy matching - always pre-fetch valid codes via GET /companies/{companyId}/codes/{codeResource} before create or update operations.
The SCIM and REST APIs are entirely separate systems with no shared state: SCIM deprovisioning a user does not update the HR employee record, and REST API termination does not automatically revoke IdP-managed portal access unless SCIM is also configured.
Rate limits are not publicly documented; Paylocity recommends contacting integration support for throughput guidance, which creates uncertainty for high-volume sync jobs. SSN and other sensitive fields are masked in all API responses regardless of scope, so any downstream system expecting those fields will receive redacted data.
Automate Paylocity workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.