Stitchflow
Lightspeed logo

Lightspeed 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

Lightspeed Retail (R-Series) exposes a REST API at https://api.lightspeedapp.com/API/V3/Account/{accountID} authenticated via OAuth 2.0. Access tokens expire after 30 minutes; proactive refresh_token rotation is required to avoid mid-operation failures. The accountID is not the OAuth client_id - it must be resolved separately via GET /API/V3/Account.json immediately after token exchange, and is required for every subsequent call.

This documentation covers R-Series only. Retail X-Series uses a different base URL (https://api.lightspeedhq.com) with a distinct endpoint structure and less publicly documented employee management surface. Restaurant and eCom APIs are separate systems entirely.

Any identity graph built on this API must treat each product line as an independent identity domain with no cross-product linkage.

API quick reference

Has user APIYes
Auth methodOAuth 2.0
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredEnterprise

Authentication

Auth method: OAuth 2.0

Setup steps

  1. Register an application at https://cloud.lightspeedapp.com/oauth/register.php to obtain a client_id and client_secret.
  2. Redirect the merchant to the authorization URL: https://cloud.lightspeedapp.com/oauth/authorize.php?response_type=code&client_id={client_id}&scope={scopes}
  3. Exchange the returned authorization code for an access_token and refresh_token via POST to https://cloud.lightspeedapp.com/oauth/access_token.php.
  4. Include the access token in all API requests as an Authorization header: 'Authorization: Bearer {access_token}'.
  5. Use the refresh_token to obtain a new access_token before expiry (tokens expire in 30 minutes).

Required scopes

Scope Description Required for
employee:all Full read/write access to employee (user) records. Creating, reading, updating, and deleting employee records.
employee:read Read-only access to employee records. Listing and retrieving employee details.
systemuserroles:all Access to system user roles. Reading and assigning roles to employees.

User object / data model

Field Type Description On create On update Notes
employeeID integer Unique identifier for the employee. auto-assigned read-only Used as path parameter for individual employee operations.
firstName string Employee's first name. required optional
lastName string Employee's last name. required optional
username string Login username for the employee. required optional Must be unique within the account.
password string Employee login password. optional optional Write-only; never returned in responses.
pin string POS PIN for the employee. optional optional Write-only; used for POS terminal login.
email string Employee's email address. optional optional
role object Role assigned to the employee (e.g., Manager, Cashier). optional optional Contains roleID and roleName. Roles are managed separately via /SystemUserRole endpoints.
employeeRoleID integer ID of the role assigned to the employee. optional optional
archived boolean Whether the employee record is archived (soft-deleted). optional optional Set to true to deactivate without deleting.
timeStamp datetime Last modification timestamp (ISO 8601). auto-assigned auto-assigned Useful for polling-based sync.
contactID integer Associated contact record ID. optional optional Links employee to a Contact object for additional details.
hourlyWage decimal Employee's hourly wage. optional optional
doNotExport boolean Flag to exclude employee from exports. optional optional

Core endpoints

List all employees

  • Method: GET
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/Employee.json
  • Watch out for: Returns up to 100 records. Use ?offset=100 to paginate. Archived employees are included unless filtered with ?archived=false.

Request example

GET /API/V3/Account/12345/Employee.json
Authorization: Bearer {access_token}

Response example

{
  "@attributes": {"count":"2","offset":"0"},
  "Employee": [
    {"employeeID":"1","firstName":"Jane","lastName":"Doe","username":"jdoe","archived":"false"}
  ]
}

Get single employee

  • Method: GET
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/Employee/{employeeID}.json
  • Watch out for: Password and PIN fields are never returned in GET responses.

Request example

GET /API/V3/Account/12345/Employee/1.json
Authorization: Bearer {access_token}

Response example

{
  "Employee": {
    "employeeID":"1",
    "firstName":"Jane",
    "lastName":"Doe",
    "username":"jdoe",
    "email":"jane@example.com",
    "archived":"false"
  }
}

Create employee

  • Method: POST
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/Employee.json
  • Watch out for: Username must be unique. Duplicate usernames return a 409 conflict. Password is write-only and not echoed back.

Request example

POST /API/V3/Account/12345/Employee.json
Content-Type: application/json

{"Employee":{"firstName":"John","lastName":"Smith","username":"jsmith","password":"secret"}}

Response example

{
  "Employee": {
    "employeeID":"42",
    "firstName":"John",
    "lastName":"Smith",
    "username":"jsmith",
    "archived":"false"
  }
}

Update employee

  • Method: PUT
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/Employee/{employeeID}.json
  • Watch out for: Uses full PUT semantics on the Lightspeed side; omitting fields may reset them. Send all desired field values.

Request example

PUT /API/V3/Account/12345/Employee/42.json
Content-Type: application/json

{"Employee":{"email":"john@example.com","employeeRoleID":"3"}}

Response example

{
  "Employee": {
    "employeeID":"42",
    "firstName":"John",
    "email":"john@example.com",
    "archived":"false"
  }
}

Archive (deactivate) employee

  • Method: PUT
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/Employee/{employeeID}.json
  • Watch out for: Lightspeed does not expose a DELETE endpoint for employees. Archiving (archived=true) is the only supported deactivation method.

Request example

PUT /API/V3/Account/12345/Employee/42.json
Content-Type: application/json

{"Employee":{"archived":"true"}}

Response example

{
  "Employee": {
    "employeeID":"42",
    "archived":"true"
  }
}

List employee roles

  • Method: GET
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/EmployeeRole.json
  • Watch out for: Role IDs are account-specific; do not assume consistent IDs across different Lightspeed accounts.

Request example

GET /API/V3/Account/12345/EmployeeRole.json
Authorization: Bearer {access_token}

Response example

{
  "EmployeeRole": [
    {"employeeRoleID":"1","name":"Manager"},
    {"employeeRoleID":"2","name":"Cashier"}
  ]
}

Search employees by modified timestamp

  • Method: GET
  • URL: https://api.lightspeedapp.com/API/V3/Account/{accountID}/Employee.json?timeStamp=%3E%2C{ISO8601_datetime}
  • Watch out for: The timeStamp filter uses URL-encoded operators (e.g., %3E%2C for >,). This is the recommended approach for incremental sync polling.

Request example

GET /API/V3/Account/12345/Employee.json?timeStamp=%3E%2C2024-01-01T00:00:00+00:00
Authorization: Bearer {access_token}

Response example

{
  "@attributes": {"count":"3"},
  "Employee": [
    {"employeeID":"5","firstName":"Alice","timeStamp":"2024-06-01T10:00:00+00:00"}
  ]
}

Get account info (resolve accountID)

  • Method: GET
  • URL: https://api.lightspeedapp.com/API/V3/Account.json
  • Watch out for: The accountID is required for all other API calls. Retrieve it first after OAuth token exchange.

Request example

GET /API/V3/Account.json
Authorization: Bearer {access_token}

Response example

{
  "Account": {
    "accountID":"12345",
    "name":"My Store",
    "timeZone":"America/New_York"
  }
}

Rate limits, pagination, and events

  • Rate limits: Lightspeed Retail API uses a leaky-bucket rate limiting model. Each account has a bucket with a maximum capacity of 60 units. Each API request costs 1 unit. The bucket refills at 1 unit per second. If the bucket is full, requests return HTTP 429.
  • Rate-limit headers: Yes
  • Retry-After header: No
  • Rate-limit notes: Response headers include X-LS-API-Bucket-Level (current bucket usage) and X-LS-API-Drip-Rate (refill rate). When HTTP 429 is returned, back off and retry after bucket drains. No explicit Retry-After header is documented.
  • Pagination method: offset
  • Default page size: 100
  • Max page size: 100
  • Pagination pointer: offset
Plan Limit Concurrent
All plans (Retail R-Series) 60 requests burst; refills at 1 req/sec 1
  • Webhooks available: No
  • Webhook notes: Lightspeed Retail (R-Series) does not offer native webhooks for employee/user events. The Lightspeed eCom (C-Series) API has webhooks but they cover commerce events (orders, products), not user management.
  • Alternative event strategy: Poll the Employee endpoint using the timeStamp filter (timeStamp>={last_sync_time}) to detect changes incrementally.

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: Enterprise
  • Endpoint: Not documented

Limitations:

  • No SCIM 2.0 endpoint is documented in official Lightspeed developer documentation for any product line (Retail, Restaurant, or eCom).
  • SSO is available on Retail X-Series plans but SCIM provisioning is not documented as a supported feature.
  • Enterprise customers should contact Lightspeed sales directly to inquire about any unpublished SCIM or directory sync capabilities.

Common scenarios

Three primary automation scenarios are supported by the Employee API. For provisioning, POST to /API/V3/Account/{accountID}/Employee.

json with firstName, lastName, username, password, email, and employeeRoleID - role IDs must be fetched first from /EmployeeRole. json and are account-specific, not portable across accounts.

Username uniqueness is enforced at the account level; handle 409 conflicts explicitly.

For incremental sync, poll /Employee.json with a timeStamp filter (timeStamp>={last_sync_ts}) to retrieve only modified records. Normalize timestamps to UTC before comparison - the API is account-timezone-aware and DST offsets can cause missed records. For offboarding, there is no DELETE endpoint; set archived=true via PUT. Note that archiving does not revoke active POS sessions or OAuth tokens - terminal logout must be coordinated separately with POS administrators.

All API responses serialize numeric IDs as strings (e.g., employeeID returns as '42', not 42). Cast types explicitly in consuming code. Pagination is offset-based with a hard maximum of 100 records per page; cursor-based pagination is not available.

Provision a new employee after HR onboarding

  1. Authenticate via OAuth 2.0 and retrieve the accountID from GET /API/V3/Account.json.
  2. Fetch available roles via GET /API/V3/Account/{accountID}/EmployeeRole.json to map the correct employeeRoleID.
  3. POST to /API/V3/Account/{accountID}/Employee.json with firstName, lastName, username, password, email, and employeeRoleID.
  4. Store the returned employeeID in your HR system for future updates.

Watch out for: Username uniqueness is enforced at the account level. Pre-check or handle 409 conflicts gracefully.

Incremental sync of employee changes

  1. Store the timestamp of the last successful sync.
  2. Poll GET /API/V3/Account/{accountID}/Employee.json?timeStamp=%3E%2C{last_sync_ts} to retrieve only modified records.
  3. Process each returned employee: update your directory if changed, flag archived=true records as deactivated.
  4. Update the stored last_sync_ts to the current time after successful processing.
  5. Respect the rate limit bucket; add a 1-second delay between paginated requests if bucket level is high.

Watch out for: Timestamps are account-timezone-aware. Normalize to UTC before comparison to avoid DST-related missed records.

Deactivate an employee upon offboarding

  1. Look up the employee by username using GET /API/V3/Account/{accountID}/Employee.json?username={username} to retrieve their employeeID.
  2. Send PUT to /API/V3/Account/{accountID}/Employee/{employeeID}.json with body {"Employee":{"archived":"true"}} to deactivate.
  3. Optionally clear the password field by sending a PUT with a new random password to prevent any residual access.

Watch out for: Archiving does not revoke active OAuth tokens or POS sessions. Coordinate with POS administrators to ensure the employee is logged out of all terminals.

Why building this yourself is a trap

The rate limit model is a leaky-bucket with a 60-unit burst capacity and a 1 req/sec refill rate, scoped per account - not per token. Multiple integrations or services authenticating against the same Lightspeed account share the same 60-unit bucket and will contend with each other under load.

Response headers X-LS-API-Bucket-Level and X-LS-API-Drip-Rate expose current state; there is no Retry-After header on 429 responses, so back-off logic must be implemented manually.

No SCIM 2.0 endpoint is documented for any Lightspeed product line. SSO is available on Retail X-Series but SCIM provisioning is not documented as a supported feature. Any identity graph integration must rely entirely on the REST Employee API with polling-based sync, as native webhooks for employee events are not available in R-Series.

The eCom webhook system covers commerce events only and cannot substitute for user lifecycle signals.

Automate Lightspeed 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

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste