Stitchflow
Freshservice logo

Freshservice User Management API Guide

API workflow

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

UpdatedMar 6, 2026

Summary and recommendation

The Freshservice REST API (v2) uses HTTP Basic Auth with an API key as the username and any non-empty string as the password; there is no OAuth 2.0 option for server-to-server calls. The API key is scoped to the generating agent's permissions, so integrations should use a dedicated admin-level service account key.

Agents and Requesters are entirely separate API resources - /api/v2/agents and /api/v2/requesters - and operations on one object type do not affect the other.

Rate limits are enforced per account (not per key), meaning multiple integrations sharing one Freshservice account draw from the same bucket: 50 req/min on Starter up to 400 req/min on Enterprise, with HTTP 429 and a Retry-After header on breach.

Pagination is offset-based using page and per_page (max 100); there is no cursor, so large datasets require sequential page iteration.

API quick reference

Has user APIYes
Auth methodHTTP Basic Auth using API key as username and any string as password (e.g., 'X'). API key found under Profile Settings in Freshservice.
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredPro or Enterprise (SCIM provisioning available via marketplace apps on Pro+; native SCIM endpoint on Enterprise)

Authentication

Auth method: HTTP Basic Auth using API key as username and any string as password (e.g., 'X'). API key found under Profile Settings in Freshservice.

Setup steps

  1. Log in to Freshservice as an admin.
  2. Navigate to Profile Settings (top-right avatar menu).
  3. Copy the API Key displayed on the page.
  4. Use the API key as the username in HTTP Basic Auth; use any non-empty string (e.g., 'X') as the password.
  5. Base64-encode 'apikey:X' and pass as Authorization: Basic header.

User object / data model

Field Type Description On create On update Notes
id integer Unique system-generated ID auto read-only Used in URL path for updates/deletes
first_name string First name of the agent/requester required optional
last_name string Last name optional optional
email string Primary email address; must be unique required optional Used as login identifier
phone string Phone number optional optional
mobile_phone_number string Mobile phone number optional optional
job_title string Job title optional optional
department_ids array[integer] IDs of departments the user belongs to optional optional Agents use department_ids; requesters also support department_ids
location_id integer ID of the user's location optional optional
role_ids array[integer] Agent role IDs assigned (agents only) required for agents optional At least one role required when creating an agent
group_ids array[integer] Agent group memberships (agents only) optional optional
occasional boolean Whether agent is an occasional (non-full-time) agent optional optional Defaults to false
active boolean Whether the user account is active auto (true) optional Set false to deactivate
time_zone string User's time zone (e.g., 'Eastern Time (US & Canada)') optional optional
language string Preferred language code (e.g., 'en') optional optional
custom_fields object Key-value map of custom field values optional optional Field keys are account-specific
created_at datetime ISO 8601 timestamp of creation auto read-only
updated_at datetime ISO 8601 timestamp of last update auto auto
reporting_manager_id integer ID of the user's reporting manager (requesters) optional optional Requester-specific field
vip_user boolean Whether requester is flagged as VIP optional optional Requester-specific field

Core endpoints

List Agents

  • Method: GET
  • URL: https://<domain>.freshservice.com/api/v2/agents
  • Watch out for: Returns only active agents by default. Use ?active=false to list deactivated agents.

Request example

GET /api/v2/agents?per_page=100&page=1
Authorization: Basic <base64(apikey:X)>

Response example

{
  "agents": [
    {"id": 1, "first_name": "Jane", "email": "jane@acme.com", "active": true}
  ]
}

Create Agent

  • Method: POST
  • URL: https://<domain>.freshservice.com/api/v2/agents
  • Watch out for: roles array is required; each entry needs role_id and assignment_scope. Creating an agent consumes a licensed seat.

Request example

POST /api/v2/agents
Content-Type: application/json
{
  "first_name": "Jane",
  "email": "jane@acme.com",
  "roles": [{"role_id": 1, "assignment_scope": "entire_helpdesk"}]
}

Response example

{
  "agent": {
    "id": 42,
    "email": "jane@acme.com",
    "active": true,
    "created_at": "2024-01-10T10:00:00Z"
  }
}

Update Agent

  • Method: PUT
  • URL: https://<domain>.freshservice.com/api/v2/agents/{id}
  • Watch out for: Uses PUT (full-style), but only supplied fields are updated. Email cannot be changed via API if SSO is enabled.

Request example

PUT /api/v2/agents/42
Content-Type: application/json
{
  "job_title": "Senior Engineer",
  "department_ids": [3]
}

Response example

{
  "agent": {
    "id": 42,
    "job_title": "Senior Engineer",
    "updated_at": "2024-06-01T12:00:00Z"
  }
}

Deactivate Agent

  • Method: DELETE
  • URL: https://<domain>.freshservice.com/api/v2/agents/{id}
  • Watch out for: DELETE deactivates the agent (soft delete), not permanent removal. The agent record is retained.

Request example

DELETE /api/v2/agents/42
Authorization: Basic <base64(apikey:X)>

Response example

HTTP 204 No Content

List Requesters

  • Method: GET
  • URL: https://<domain>.freshservice.com/api/v2/requesters
  • Watch out for: Requesters and Agents are separate objects. An agent is not returned in /requesters and vice versa.

Request example

GET /api/v2/requesters?per_page=100&page=1
Authorization: Basic <base64(apikey:X)>

Response example

{
  "requesters": [
    {"id": 101, "first_name": "Bob", "email": "bob@acme.com"}
  ]
}

Create Requester

  • Method: POST
  • URL: https://<domain>.freshservice.com/api/v2/requesters
  • Watch out for: Email must be unique across both agents and requesters in the account.

Request example

POST /api/v2/requesters
Content-Type: application/json
{
  "first_name": "Bob",
  "email": "bob@acme.com",
  "department_ids": [2]
}

Response example

{
  "requester": {
    "id": 101,
    "email": "bob@acme.com",
    "active": true
  }
}

Convert Requester to Agent

  • Method: PUT
  • URL: https://<domain>.freshservice.com/api/v2/requesters/{id}/convert_to_agent
  • Watch out for: Consumes an agent license seat. Roles must be assigned separately after conversion.

Request example

PUT /api/v2/requesters/101/convert_to_agent
Authorization: Basic <base64(apikey:X)>

Response example

{
  "agent": {
    "id": 101,
    "email": "bob@acme.com",
    "active": true
  }
}

Get Agent by ID

  • Method: GET
  • URL: https://<domain>.freshservice.com/api/v2/agents/{id}
  • Watch out for: Returns 404 if the agent ID belongs to a deactivated agent and the account has purged it.

Request example

GET /api/v2/agents/42
Authorization: Basic <base64(apikey:X)>

Response example

{
  "agent": {
    "id": 42,
    "email": "jane@acme.com",
    "active": true,
    "role_ids": [1]
  }
}

Rate limits, pagination, and events

  • Rate limits: Rate limits are plan-based and applied per Freshservice account. Limits are enforced per minute. When exceeded, the API returns HTTP 429.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: Response headers include X-RateLimit-Total, X-RateLimit-Remaining, X-RateLimit-Used-CurrentRequest, and Retry-After on 429 responses.
  • Pagination method: offset
  • Default page size: 30
  • Max page size: 100
  • Pagination pointer: page and per_page
Plan Limit Concurrent
Starter 50 requests/min 0
Growth 100 requests/min 0
Pro 200 requests/min 0
Enterprise 400 requests/min 0
  • Webhooks available: Yes
  • Webhook notes: Freshservice supports webhooks via Automation rules (Workflow Automator and Event-based rules). Webhooks can be triggered on ticket, agent, or requester events by configuring an HTTP action in the automator.
  • Alternative event strategy: Polling the /agents and /requesters endpoints with updated_since filter for change detection.
  • Webhook events: ticket.created, ticket.updated, agent.created, agent.updated, requester.created, requester.updated

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Pro or Enterprise (SCIM provisioning available via marketplace apps on Pro+; native SCIM endpoint on Enterprise)

  • Endpoint: https://scim.freshservice.com/scim/v2

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

Limitations:

  • SSO must be configured before enabling SCIM provisioning.
  • SCIM is accessed via marketplace apps for Okta, Azure AD (Entra ID), and OneLogin; not a generic open SCIM endpoint on lower plans.
  • SCIM-provisioned users are created as requesters by default; agent promotion requires manual action or API.
  • Custom attribute mapping is limited to fields supported by the IdP connector.
  • Deprovisioning via SCIM deactivates the user but does not permanently delete the record.

Common scenarios

Three scenarios cover the majority of programmatic identity lifecycle work against Freshservice. For provisioning, POST to /api/v2/requesters with first_name, last_name, email, department_ids, and job_title.

if the user also needs agent access, follow with PUT /api/v2/requesters/{id}/convert_to_agent - this immediately consumes a billable seat, and roles must be assigned in a subsequent PUT /api/v2/agents/{id}. For deprovisioning, locate the user via GET /api/v2/agents?

email= or GET /api/v2/requesters? email=, then issue DELETE on the appropriate resource; DELETE is a soft deactivation - the record and email address are retained, so re-provisioning the same user requires reactivation rather than a new record.

For incremental sync into an external identity graph, use GET /api/v2/agents? updated_since=&per_page=100 and paginate until the response count falls below per_page; run a separate pass with ?

active=false to capture deactivated agents, which are excluded from the default response.

Provision a new employee as a Freshservice requester

  1. POST /api/v2/requesters with first_name, last_name, email, department_ids, job_title.
  2. Capture the returned requester id for future updates.
  3. Optionally PATCH custom_fields to populate HR-specific attributes.
  4. If the employee is also IT staff, call PUT /api/v2/requesters/{id}/convert_to_agent and then PUT /api/v2/agents/{id} to assign roles.

Watch out for: Email must not already exist in the account. Converting to agent consumes a license seat immediately.

Deprovision a departing employee

  1. Identify the user: GET /api/v2/agents?email=user@acme.com or GET /api/v2/requesters?email=user@acme.com.
  2. If agent: DELETE /api/v2/agents/{id} to deactivate.
  3. If requester: DELETE /api/v2/requesters/{id} to deactivate.
  4. Verify deactivation by checking active: false in a subsequent GET.

Watch out for: DELETE is a soft deactivation. The record persists and the email remains reserved; re-provisioning the same email requires reactivation, not a new record.

Incremental sync of agent changes to an external directory

  1. Store the timestamp of the last successful sync.
  2. GET /api/v2/agents?updated_since=&per_page=100&page=1.
  3. Iterate pages until the response returns fewer records than per_page.
  4. For each returned agent, upsert into the external directory using the Freshservice id as the key.
  5. Update the stored last_sync_timestamp to the current time.

Watch out for: updated_since filters by the agent's updated_at field. Deactivated agents are not returned unless ?active=false is also passed; run a separate pass for deactivated users.

Why building this yourself is a trap

Several API behaviors create silent failure modes worth flagging explicitly. GET /api/v2/agents returns only active agents by default - omitting ?active=false means deprovisioned users are invisible to any sync that does not account for this, leaving stale identities undetected in a downstream identity graph.

Email addresses must be globally unique across both agents and requesters in the same account; a provisioning call will fail if the address exists on either object type, and the error surface is not always obvious.

The PUT /api/v2/agents/{id} endpoint behaves as a partial update despite its method - only supplied fields are modified - but email cannot be changed via API when SSO is enabled, which can cause silent no-ops in automated update flows.

Finally, SCIM provisioning at https://scim.freshservice.com/scim/v2 requires SSO to be configured first, is gated to Pro or Enterprise plans, and provisions users as requesters by default; agent promotion is not handled by the SCIM flow and requires a separate API call.

Automate Freshservice 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 6, 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