Stitchflow
Pleo logo

Pleo User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 11, 2026

Summary and recommendation

Pleo exposes a REST API at `https://external.pleo.io/v0` using OAuth 2.0, supporting both client credentials (partner/service accounts) and authorization code (user-delegated) flows. Core employee lifecycle operations - list, get, create, update, and deactivate - are available via the `/employees` resource. The API is company-scoped per credential set; multi-company management requires separate credentials per company.

Tokens are short-lived, so token refresh logic is mandatory to avoid mid-operation 401 errors. Rate limit thresholds are not publicly documented; HTTP 429 is returned on breach, and exponential backoff should be implemented as a baseline. Pagination is cursor-based using `pageToken` - offset arithmetic will not work reliably.

No webhook system is available for employee lifecycle events; polling `GET /employees` with a stored cursor is the only event-detection mechanism.

For teams building an identity graph across SaaS applications, Pleo's employee object provides the fields needed to anchor spend identity: `id` (UUID), `email`, `role` (enum: OWNER, BOOKKEEPER, MEMBER), `status` (enum: ACTIVE, INVITED, DEACTIVATED), `departmentId`, and `companyId`.

These fields are sufficient to join Pleo identity records against a canonical employee directory and detect provisioning drift - active Pleo accounts with no corresponding active directory record, or DEACTIVATED records still appearing as active in upstream systems.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (client credentials flow for partner/API access; authorization code flow for user-delegated access)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise (Beyond plan or higher; SAML SSO must be enabled first)

Authentication

Auth method: OAuth 2.0 (client credentials flow for partner/API access; authorization code flow for user-delegated access)

Setup steps

  1. Register an application in the Pleo Developer Portal (developers.pleo.io) to obtain a client_id and client_secret.
  2. Request an access token via POST to https://external.pleo.io/v0/auth/headless/token using client_credentials grant type.
  3. Include the returned Bearer token in the Authorization header for all subsequent API requests.
  4. Ensure the token is refreshed before expiry; Pleo tokens are short-lived.

Required scopes

Scope Description Required for
read:employees Read employee (user) records including profile and status. GET /employees, GET /employees/{id}
write:employees Create and update employee records. POST /employees, PATCH /employees/{id}
read:company Read company-level metadata. GET /companies/{id}

User object / data model

Field Type Description On create On update Notes
id string (UUID) Unique identifier for the employee. system-generated immutable Used as path parameter in employee-specific endpoints.
firstName string Employee's first name. required optional
lastName string Employee's last name. required optional
email string Employee's work email address; used as login identifier. required optional Must be unique within the company.
role string (enum) Employee role within Pleo: OWNER, BOOKKEEPER, MEMBER. optional (defaults to MEMBER) optional Controls permissions within the Pleo platform.
status string (enum) Account status: ACTIVE, INVITED, DEACTIVATED. system-set to INVITED on creation can be set to DEACTIVATED to offboard Deactivating does not delete the employee record.
departmentId string (UUID) ID of the department the employee belongs to. optional optional Department must exist before assignment.
spendingLimit object Monthly spending limit configuration for the employee's card. optional optional Contains amount (integer, minor currency units) and currency fields.
locale string BCP 47 locale tag for the employee (e.g., en-GB). optional optional
companyId string (UUID) ID of the company the employee belongs to. system-set immutable Derived from the authenticated API client's company context.

Core endpoints

List Employees

  • Method: GET
  • URL: https://external.pleo.io/v0/employees
  • Watch out for: Pagination uses cursor-based pageToken; do not rely on offset arithmetic.

Request example

GET /v0/employees?pageSize=50 HTTP/1.1
Authorization: Bearer {access_token}

Response example

{
  "data": [{"id":"uuid","firstName":"Jane","lastName":"Doe","email":"jane@co.com","status":"ACTIVE"}],
  "nextPageToken": "abc123"
}

Get Employee by ID

  • Method: GET
  • URL: https://external.pleo.io/v0/employees/{employeeId}
  • Watch out for: Returns 404 if the employee ID does not belong to the authenticated client's company.

Request example

GET /v0/employees/uuid-1234 HTTP/1.1
Authorization: Bearer {access_token}

Response example

{
  "data": {"id":"uuid-1234","firstName":"Jane","email":"jane@co.com","status":"ACTIVE","role":"MEMBER"}
}

Create Employee (Invite)

  • Method: POST
  • URL: https://external.pleo.io/v0/employees
  • Watch out for: Creating an employee triggers an invitation email to the provided address immediately.

Request example

POST /v0/employees HTTP/1.1
Authorization: Bearer {access_token}
Content-Type: application/json

{"firstName":"John","lastName":"Smith","email":"john@co.com"}

Response example

{
  "data": {"id":"uuid-5678","status":"INVITED","email":"john@co.com"}
}

Update Employee

  • Method: PATCH
  • URL: https://external.pleo.io/v0/employees/{employeeId}
  • Watch out for: Only fields included in the PATCH body are updated; omitted fields retain their current values.

Request example

PATCH /v0/employees/uuid-5678 HTTP/1.1
Authorization: Bearer {access_token}
Content-Type: application/json

{"departmentId":"dept-uuid","role":"BOOKKEEPER"}

Response example

{
  "data": {"id":"uuid-5678","role":"BOOKKEEPER","departmentId":"dept-uuid"}
}

Deactivate Employee

  • Method: DELETE
  • URL: https://external.pleo.io/v0/employees/{employeeId}
  • Watch out for: This deactivates the employee and revokes card access; it does not permanently delete the record or historical expense data.

Request example

DELETE /v0/employees/uuid-5678 HTTP/1.1
Authorization: Bearer {access_token}

Response example

HTTP 204 No Content

List Departments

  • Method: GET
  • URL: https://external.pleo.io/v0/departments
  • Watch out for: Department IDs are required when assigning employees to departments; fetch this list first.

Request example

GET /v0/departments HTTP/1.1
Authorization: Bearer {access_token}

Response example

{
  "data": [{"id":"dept-uuid","name":"Engineering"}]
}

Get Company

  • Method: GET
  • URL: https://external.pleo.io/v0/companies/{companyId}
  • Watch out for: The companyId is scoped to the authenticated client; cross-company access is not supported.

Request example

GET /v0/companies/co-uuid HTTP/1.1
Authorization: Bearer {access_token}

Response example

{
  "data": {"id":"co-uuid","name":"Acme Corp","currency":"EUR"}
}

Rate limits, pagination, and events

  • Rate limits: Pleo does not publicly document specific rate limit thresholds in its developer docs as of the knowledge cutoff. Limits are enforced but exact values are not published.
  • Rate-limit headers: Yes
  • Retry-After header: No
  • Rate-limit notes: HTTP 429 is returned when rate limits are exceeded. Retry-After header presence is not confirmed in official docs. Implement exponential backoff.
  • Pagination method: cursor
  • Default page size: 50
  • Max page size: 100
  • Pagination pointer: pageToken
Plan Limit Concurrent
All plans 0
  • Webhooks available: No
  • Webhook notes: Pleo's public developer API documentation does not describe a webhook system for user/employee lifecycle events as of the knowledge cutoff.
  • Alternative event strategy: Poll GET /employees with a stored cursor/pageToken to detect new or changed employee records.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise (Beyond plan or higher; SAML SSO must be enabled first)

  • Endpoint: https://external.pleo.io/scim/v2

  • Supported operations: GET /Users, GET /Users/{id}, POST /Users, PATCH /Users/{id}, PUT /Users/{id}, DELETE /Users/{id}

Limitations:

  • SCIM provisioning is currently documented only for Okta and Microsoft Entra ID (Azure AD) integrations.
  • SAML SSO must be configured and active before SCIM can be enabled.
  • Group/department sync via SCIM is not confirmed in official documentation.
  • Available on Enterprise/Beyond plan only; not available on Starter, Essential, or Advanced plans.
  • Google Workspace and OneLogin SCIM integrations are not officially supported.

Common scenarios

Three primary automation scenarios are supported by the current API surface.

Onboard: POST /v0/employees with firstName, lastName, and email immediately creates the record and fires an invitation email - there is no draft state. Capture the returned id, then PATCH /v0/employees/{id} to set departmentId, role, and spendingLimit. Note that spendingLimit values use minor currency units (cents), not decimal amounts.

Offboard: Locate the employee UUID via GET /v0/employees filtered by email if not already stored in your identity graph. DELETE /v0/employees/{id} deactivates the account and revokes card access immediately. The record and all historical expense data are retained; a subsequent GET /v0/employees/{id} should return status: DEACTIVATED as confirmation.

SCIM sync via Okta or Entra ID: Requires the Beyond/Enterprise plan with SAML SSO active. The SCIM base URL is https://external.pleo.io/scim/v2. SCIM is documented only for Okta and Microsoft Entra ID; Google Workspace and OneLogin are not officially supported. Group/department sync via SCIM is unconfirmed in official documentation. The SCIM Bearer token is generated once in Pleo admin - if lost, a new token must be generated and updated in the IdP connector.

Onboard a new employee

  1. POST /v0/employees with firstName, lastName, and email to create and invite the employee.
  2. Capture the returned employee id from the response.
  3. PATCH /v0/employees/{id} to assign departmentId, role, and spendingLimit as needed.
  4. Employee receives invitation email and completes account setup independently.

Watch out for: The invitation email fires on POST creation; ensure the email address is correct before calling the endpoint.

Offboard a departing employee

  1. GET /v0/employees to locate the employee's UUID by email if not already stored.
  2. DELETE /v0/employees/{id} to deactivate the account and revoke card access.
  3. Verify the employee's status returns DEACTIVATED on a subsequent GET /v0/employees/{id}.

Watch out for: DELETE deactivates but does not delete; expense history and records are retained for audit purposes.

Sync employees via SCIM with Okta

  1. Ensure the company is on the Beyond/Enterprise plan.
  2. Configure SAML SSO in Pleo admin settings and verify it is active.
  3. In Pleo admin, navigate to Integrations > Okta and retrieve the SCIM base URL and Bearer token.
  4. In Okta, add the Pleo app, set the SCIM connector base URL to https://external.pleo.io/scim/v2, and paste the Bearer token.
  5. Enable SCIM provisioning features (Create Users, Update User Attributes, Deactivate Users) in Okta.
  6. Assign users or groups in Okta to push provisioning events to Pleo.

Watch out for: SCIM token is generated once in Pleo admin; if lost, a new token must be generated and updated in Okta.

Why building this yourself is a trap

The most common integration failure points with Pleo's API are predictable but non-obvious from the docs alone. Creating an employee immediately sends an invitation email; a test run against production will notify real users.

The DELETE endpoint deactivates, not deletes - callers that treat a 200 response as full removal will leave ghost records in their identity graph. SCIM cannot be enabled without SAML SSO already active and verified; attempting to configure SCIM first will block provisioning entirely.

The API is single-company per credential set, so any multi-tenant or multi-entity architecture requires explicit credential management per company. Finally, SCIM provisioning is gated to Enterprise/Beyond - teams that build SCIM-dependent workflows on lower-tier plans will hit a hard wall when attempting to enable the integration.

Automate Pleo 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.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 11, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen