Stitchflow
TravelPerk logo

TravelPerk User Management API Guide

API workflow

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

UpdatedMar 18, 2026

Summary and recommendation

TravelPerk exposes a versioned REST API at https://app.travelperk.com/api/v2 authenticated via OAuth 2.0 authorization code flow.

Core user lifecycle operations - list, get, create, update, deactivate, delete - are available under the users:read and users:write scopes.

The API supports offset-based pagination with a maximum page size of 200 and returns HTTP 429 on rate limit breach;

exact rate limit thresholds are not publicly documented, so exponential backoff on 429 is mandatory.

For IdP-driven provisioning, a separate SCIM 2.0 endpoint is available at https://app.travelperk.com/api/scim/v2 on the Premium plan, using a distinct bearer token generated in TravelPerk Settings - not the OAuth access token.

Integrating TravelPerk into an identity graph requires mapping the user id (UUID) and email fields as join keys, with manager_id, cost_center, and travel_policy as enrichment attributes that connect the user node to organizational and policy subgraphs.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (authorization code flow)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredPremium

Authentication

Auth method: OAuth 2.0 (authorization code flow)

Setup steps

  1. Register an OAuth application in the TravelPerk developer portal to obtain a client_id and client_secret.
  2. Redirect the user to https://app.travelperk.com/oauth2/authorize with response_type=code, client_id, redirect_uri, and desired scopes.
  3. Exchange the returned authorization code for an access token via POST to https://app.travelperk.com/oauth2/token.
  4. Include the access token in all API requests as a Bearer token in the Authorization header.
  5. Refresh the access token using the refresh_token grant type before expiry.

Required scopes

Scope Description Required for
users:read Read user profiles and list users in the organization. GET /users, GET /users/{id}
users:write Create, update, and delete user profiles. POST /users, PATCH /users/{id}, DELETE /users/{id}
companies:read Read company and workspace information. GET /companies endpoints used in user context

User object / data model

Field Type Description On create On update Notes
id string (UUID) Unique identifier for the user. system-generated immutable Used as path parameter for single-user operations.
first_name string User's first name. required optional
last_name string User's last name. required optional
email string User's email address; used as login identifier. required optional Must be unique within the organization.
role string (enum) User role within TravelPerk (e.g., traveler, travel_manager, company_admin). optional optional Determines permissions within the platform.
phone_number string User's phone number in E.164 format. optional optional
language string (ISO 639-1) Preferred language for the user interface. optional optional
gender string (enum) User's gender (male, female, other). optional optional Used for travel document and booking purposes.
date_of_birth string (YYYY-MM-DD) User's date of birth. optional optional
nationality string (ISO 3166-1 alpha-2) User's nationality country code. optional optional
invoicing_profiles array Invoicing profiles associated with the user. optional optional
travel_policy object Travel policy assigned to the user. optional optional References a travel policy by ID.
manager_id string (UUID) ID of the user's manager for approval workflows. optional optional
cost_center string Cost center code for expense allocation. optional optional
is_active boolean Whether the user account is active. optional (defaults to true) optional Setting to false deactivates the user without deletion.

Core endpoints

List Users

  • Method: GET
  • URL: https://app.travelperk.com/api/v2/users
  • Watch out for: Pagination uses offset/limit; max limit is 200. Requests beyond total count return an empty results array.

Request example

GET /api/v2/users?limit=10&offset=0
Authorization: Bearer {access_token}

Response example

{
  "results": [{"id":"uuid","first_name":"Jane","last_name":"Doe","email":"jane@example.com"}],
  "total": 42,
  "offset": 0,
  "limit": 10
}

Get User

  • Method: GET
  • URL: https://app.travelperk.com/api/v2/users/{id}
  • Watch out for: Returns 404 if the user does not belong to the authenticated OAuth app's organization.

Request example

GET /api/v2/users/user-uuid
Authorization: Bearer {access_token}

Response example

{
  "id": "user-uuid",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@example.com",
  "role": "traveler",
  "is_active": true
}

Create User

  • Method: POST
  • URL: https://app.travelperk.com/api/v2/users
  • Watch out for: Email must be unique within the organization; duplicate email returns 422.

Request example

POST /api/v2/users
Authorization: Bearer {access_token}
Content-Type: application/json

{"first_name":"Jane","last_name":"Doe","email":"jane@example.com","role":"traveler"}

Response example

{
  "id": "new-user-uuid",
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@example.com",
  "role": "traveler"
}

Update User

  • Method: PATCH
  • URL: https://app.travelperk.com/api/v2/users/{id}
  • Watch out for: Only fields included in the request body are updated; omitted fields retain their current values.

Request example

PATCH /api/v2/users/user-uuid
Authorization: Bearer {access_token}
Content-Type: application/json

{"role":"travel_manager","cost_center":"CC-001"}

Response example

{
  "id": "user-uuid",
  "role": "travel_manager",
  "cost_center": "CC-001"
}

Delete User

  • Method: DELETE
  • URL: https://app.travelperk.com/api/v2/users/{id}
  • Watch out for: Deletion is permanent. Consider setting is_active=false via PATCH to deactivate without data loss.

Request example

DELETE /api/v2/users/user-uuid
Authorization: Bearer {access_token}

Response example

HTTP 204 No Content

List Travel Policies

  • Method: GET
  • URL: https://app.travelperk.com/api/v2/travel_policies
  • Watch out for: Policy IDs are needed when assigning travel_policy to a user during create or update.

Request example

GET /api/v2/travel_policies
Authorization: Bearer {access_token}

Response example

{
  "results": [{"id":"policy-uuid","name":"Economy Policy"}],
  "total": 3
}

List Groups (Departments)

  • Method: GET
  • URL: https://app.travelperk.com/api/v2/groups
  • Watch out for: Groups map to departments; group membership is managed separately from user profile fields.

Request example

GET /api/v2/groups
Authorization: Bearer {access_token}

Response example

{
  "results": [{"id":"group-uuid","name":"Engineering"}],
  "total": 5
}

Add User to Group

  • Method: POST
  • URL: https://app.travelperk.com/api/v2/groups/{group_id}/members
  • Watch out for: User must already exist before being added to a group; adding a non-existent user returns 404.

Request example

POST /api/v2/groups/group-uuid/members
Authorization: Bearer {access_token}
Content-Type: application/json

{"user_id":"user-uuid"}

Response example

HTTP 201 Created
{"group_id":"group-uuid","user_id":"user-uuid"}

Rate limits, pagination, and events

  • Rate limits: TravelPerk enforces rate limits per API token. The developer docs note limits but do not publish exact per-plan numbers publicly.
  • Rate-limit headers: Yes
  • Retry-After header: No
  • Rate-limit notes: The API returns HTTP 429 when rate limits are exceeded. Rate limit headers are present in responses per the developer docs, but specific header names and exact limits are not publicly documented. Retry-After behavior is not explicitly documented.
  • Pagination method: offset
  • Default page size: 10
  • Max page size: 200
  • Pagination pointer: offset / limit
Plan Limit Concurrent
All authenticated API tokens Not publicly specified in current docs 0
  • Webhooks available: No
  • Webhook notes: TravelPerk's public developer documentation does not describe outbound webhook support for user management events as of the current documentation review.
  • Alternative event strategy: Poll the GET /users endpoint periodically to detect changes, or use SCIM provisioning for IdP-driven sync.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Premium

  • Endpoint: https://app.travelperk.com/api/scim/v2

  • Supported operations: GET /Users (list users), GET /Users/{id} (get user), POST /Users (create user), PUT /Users/{id} (replace user), PATCH /Users/{id} (update user), DELETE /Users/{id} (delete/deprovision user), GET /Groups (list groups), POST /Groups (create group), PATCH /Groups/{id} (update group membership), DELETE /Groups/{id} (delete group)

Limitations:

  • Requires Premium plan; not available on Starter or Pro plans.
  • SCIM token is generated within TravelPerk settings and is separate from OAuth 2.0 tokens.
  • IdP-specific connector setup (e.g., Okta, Azure AD) must be configured on the IdP side using the TravelPerk SCIM base URL and token.
  • Not all user profile fields available via the REST API are writable via SCIM; travel-specific fields (e.g., travel policy) may require REST API calls.
  • Group provisioning support may vary by IdP connector configuration.

Common scenarios

Three scenarios cover the majority of programmatic user management needs.

For new-hire provisioning: POST to /api/v2/users with the required fields, then retrieve policy IDs via GET /api/v2/travel_policies and assign via a separate PATCH

travel policy cannot be guaranteed atomic in the creation POST.

For offboarding: prefer PATCH with is_active=false over DELETE;

the DELETE endpoint is irreversible and eliminates the audit trail.

For IdP sync via SCIM: generate a SCIM token in TravelPerk Settings, configure the IdP connector against the SCIM base URL, and map userName to email and name.givenName to first_name;

note that travel-specific fields such as travel policy are not writable via SCIM and require direct REST API calls post-sync.

Group membership is managed via a separate /api/v2/groups/{group_id}/members endpoint and is not part of the core user object.

Provision a new employee and assign a travel policy

  1. POST /api/v2/users with first_name, last_name, email, and role=traveler to create the user.
  2. GET /api/v2/travel_policies to retrieve available policy IDs.
  3. PATCH /api/v2/users/{id} with the desired travel_policy ID to assign the policy.
  4. Optionally POST /api/v2/groups/{group_id}/members to add the user to their department group.

Watch out for: Travel policy assignment requires a separate PATCH after creation; it cannot always be set atomically in the POST body depending on API version behavior.

Deprovision a departing employee

  1. PATCH /api/v2/users/{id} with is_active=false to deactivate the account without permanent deletion.
  2. Verify the user no longer appears in active user listings by checking GET /api/v2/users with an active filter if supported.
  3. If permanent removal is required, follow with DELETE /api/v2/users/{id}.

Watch out for: DELETE is permanent and cannot be undone; deactivation via PATCH is preferred for audit trail retention.

Sync users from an IdP using SCIM

  1. Confirm the TravelPerk account is on the Premium plan.
  2. Navigate to TravelPerk Settings > Integrations > SCIM and generate a SCIM bearer token.
  3. In the IdP (e.g., Okta or Azure AD), configure a new SCIM 2.0 application using base URL https://app.travelperk.com/api/scim/v2 and the generated token.
  4. Map IdP user attributes to SCIM standard attributes (userName → email, name.givenName → first_name, etc.).
  5. Enable provisioning actions (create, update, deactivate) in the IdP connector and perform a test sync.

Watch out for: SCIM token and OAuth token are distinct; do not use the OAuth access token for SCIM requests. Some travel-specific fields are not writable via SCIM and require direct REST API calls.

Why building this yourself is a trap

The primary integration trap is token confusion: the OAuth 2.0 access token and the SCIM bearer token are entirely separate credentials with no overlap - using the OAuth token against the SCIM endpoint will fail silently or return auth errors.

A second trap is the DELETE endpoint: it is permanent and undocumented for recovery, making it unsuitable for standard offboarding flows where audit retention is required.

Rate limits present a third risk - because exact limits and header names are not publicly documented, any bulk operation such as paginating all users or batch-updating cost centers must implement defensive backoff from the start rather than after hitting production errors. Finally, the API is scoped to a single organization per OAuth token;

multi-tenant or multi-workspace architectures require separate OAuth app registrations and token management per organization.

Automate TravelPerk 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 18, 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