PeopleForce

Early access

Company API v4 is the next-generation API and is under active development. Endpoints and fields may still change.

Authentication

Authenticate v4 requests with a service account API key, and use roles to control exactly what it can reach.

API v4 authenticates with a service account API key, passed in the X-API-KEY header. Service accounts are new in v4 and are the only credential it accepts.

The important difference from earlier versions: a service account key carries no permissions of its own. On its own it can read a little reference data and nothing else. Everything it can see and do comes from the roles you assign to it — the same Roles & permissions system that governs what your people can see in PeopleForce.

Please note that API v4 currently has a subset of the endpoints available in API v3. We are currently adding new endpoints in every release.

v4 accepts service account API keys only - you can't use a Company API key or a Career API key. Equally, a service account API key only works against v4 - you can't use it to access v3, v2 or v1 APIs.

Why this changed

Company API keys have a very limited set of permissions for what can be restricted, and this is a separate mechanism from roles and permissions. As we seek to add more permissions to API keys, we decided to unify the approach to permissions between Web and API users.

Service Account API keys represents a new direction, unifying the approach to permission management.

Set up a service account

1. Create the key

Go to Settings → API keys → Generate API key, name the key, and choose the Service account type ("Service account user for taking API actions using specific roles and permissions").

Copy the key immediately and store it in your secret manager — PeopleForce does not show it again.

If Service account isn't offered as a key type, service accounts aren't enabled for your account yet. Contact us to have it turned on.

2. Create a matching role

Go to Settings → Roles & permissions, add a new role, and choose the Service account type. Give it a name describing the integration, for example Payroll export or Marketing directory sync.

Service account roles are separate from the roles you assign to people. They appear in the same list and use the same permission model, but they can only be assigned to service account API keys.

3. Attach the key and scope the role

The role form has three parts:

SectionWhat it controls
Who is assigned this role?The service account keys this role applies to. Select the key you created in step 1 — a role with no key attached grants nothing.
Company tabCompany-wide actions: managing review cycles and the org-structure lists. These aren't tied to a population.
People tabFirst Whose data can members access? — the population, built from rules such as Department is Marketing. Then What can this role see? — the fields, records, and modules the role grants for those people.

What a role can grant

Company-wide actions

Set these on the role's Company tab. Reading the org-structure lists needs no permission — any active service account key can GET them. The permissions below govern writes.

Examples below - please see API Reference for full details.

PermissionUnlocks
Manage departmentsPOST / PUT / DELETE on /departments
Manage divisionsPOST / PUT / DELETE on /divisions
Manage locationsPOST / PUT / DELETE on /locations
Manage job titlesPOST / PUT / DELETE on /job_titles
Manage job levelsPOST / PUT / DELETE on /job_levels
Manage work typesPOST / PUT / DELETE on /work_types
Manage all review cyclesGET /perform/review_cycles. Grants every cycle in the company — this one isn't narrowed by the role's population.

Per-person data

Set these on the role's People tab, under What can this role see?. They apply only to the people the role's population covers.

Examples below - please see API Reference for full details.

Sub-tabPermissionUnlocks
PersonalEach profile field and table, set to None / View / EditWhether that field appears in /people responses, and whether you can write it
JobHire datehired_on on a person
JobTermination detailsThe termination_* fields, and GET /people/{id}/lifecycles
CompensationCompensation (View / Edit)GET and write access to /people/{id}/compensation/salaries
PerformSee objectivesGET /perform/objectives
PerformSee reviewsGET /perform/review_responses
PulseSee lifecycle survey responsesGET /pulse/lifecycle_surveys and /pulse/lifecycle_survey_responses
PulseSee engagement survey responsesGET /pulse/engagement_surveys and /pulse/engagement_survey_responses

The Perform and Pulse sub-tabs only appear if your account has those products.

Edit implies View. Granting Edit on a field or on Compensation also grants read access — you don't need to set both.

Using the key

Pass the key in a request header named X-API-KEY:

curl https://app.peopleforce.io/api/v4/people \
  -H "X-API-KEY: <your_api_key>"

All API requests must be made over HTTPS — calls over plain HTTP will fail, and so will requests without authentication.

Passing the API key in the X-API-KEY header

What to expect in a response

Two behaviours surprise people moving from v1–v3, and both are deliberate:

People outside the role's population are absent, not refused. Listing endpoints return only the people the key's roles cover, so a narrowly scoped key gets a short list — or an empty one — with a 200, never a 403. A request for a specific person outside the population returns 404, because as far as that key is concerned the record doesn't exist.

Fields the role doesn't grant are omitted from the JSON, not returned as null. If the role doesn't grant Compensation or a personal field, the key is simply not present in the object. Write your integration to treat a missing key as "not permitted" rather than "empty", and don't infer that a person has no value for a field you can't see.

{
  "data": {
    "id": 1234,
    "status": "active",
    "full_name": "Dana Whitfield",
    "email": "dana@example.com",
    "department": { "id": 12, "name": "Marketing" }
  }
}

Above, date_of_birth and hired_on are absent because the role doesn't grant them — not because they're unset.

The Pulse endpoints are the exception to the first rule: they return 403 when the key's roles grant no survey access at all, rather than an empty list.

Errors

v4 returns errors as application/problem+json with a status and a message, and a detail array when there is field-level information:

{
  "status": "unauthorized",
  "message": "Invalid credentials provided."
}
StatusmessageUsual cause
401Invalid credentials provided.Missing X-API-KEY, a mistyped key, a key that isn't a service account, or a disabled key
403You are not authorized to access this resource.The key's roles don't grant this action
404The requested resource could not be found.The record doesn't exist — or is outside the role's population
400The request is invalid or cannot be processed.Malformed or missing parameters, or a body that isn't valid JSON
405The HTTP method is not allowed for this resource.The path exists but not with this verb; Allow lists the verbs it accepts
422One or more validation errors occurred.The payload failed validation; detail lists each error
500An unexpected server error occurred.A problem on our side — try again, or contact support

Disabling and revoking a key

From Settings → API keys you can disable a key with the toggle on its row, stopping it from working without deleting it — useful while pausing an integration. A disabled key gets 401 on every request.

Disabling a service account key from the API keys list

To remove a key permanently, open the menu on its row and choose Delete.

Deleting a service account key from the API keys list

Deleting an API key is permanent and immediate. Any integration using that key stops working at once, and the key cannot be recreated. Account for every integration before deleting.

Deleting a key leaves its roles in place, so a replacement key can be attached to the same role. Deleting the role instead revokes everything the key could reach while leaving the credential valid — it will authenticate and return nothing.

Troubleshooting

401 on every request

Check, in order: that the key was copied in full; that it's a Service account key and not a Company key; that it's still enabled in Settings → API keys; and that you're calling /api/v4/….

Authentication works, but every list is empty

The key has no role attached, or the role's population matches nobody. Open the role and confirm the key is selected under Who is assigned this role?, then check the rules under Whose data can members access?.

A person is in the list, but a field is missing

The role doesn't grant that field for that person. Grant it on the role's People → What can this role see? tab — under Personal for profile fields and tables, Job for hire date and termination details, or Compensation for salary data.

403 on a write, but reads work

Writes to the org-structure lists need the matching Manage … permission on the role's Company tab. Writes to a person's data need Edit rather than View on the relevant field.

On this page