Stitchflow
Autotask PSA logo

Autotask PSA User Management API Guide

API workflow

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

UpdatedFeb 27, 2026

Summary and recommendation

Autotask PSA exposes a REST API (v1.0) for full resource lifecycle management: create, read, update, and deactivate. Authentication uses three static HTTP headers-UserName (API key), Secret, and ApiIntegrationCode-with no OAuth 2.0 support; SSO credentials are entirely separate from API credentials.

The first call in any integration must be GET /zoneInformation to resolve the correct zone-specific base URL, as the subdomain varies per tenant. Stitchflow connects to Autotask via an MCP server with ~100 deep IT/identity integrations, handling zone resolution, pagination, and rate-limit coordination across integrations automatically.

API quick reference

Has user APIYes
Auth methodAPI Key + Secret + Integration Code (HTTP headers)
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredN/A — No native SCIM endpoint in Autotask PSA. SCIM provisioning is available only via third-party IdP integrations (e.g., Okta SCIM connector to Autotask).

Authentication

Auth method: API Key + Secret + Integration Code (HTTP headers)

Setup steps

  1. Log in to Autotask PSA as an administrator.
  2. Navigate to Admin > Resources (Users) and click the dropdown next to '+ New', then select 'New API User'.
  3. In the General pane, enter First Name, Last Name, and Email Address; set Security Level to 'API User (system)'.
  4. In the Security pane, copy the generated Username (Key) and Password (Secret) - the secret is shown only once.
  5. Assign or self-generate an API Integration Code (tracking identifier) from the Security tab of the API user's Resource Management page.
  6. Pass all three values as HTTP headers on every request: 'UserName', 'Secret', and 'ApiIntegrationCode', plus 'Content-Type: application/json'.
  7. Determine your zone-specific base URL by calling GET /zoneInformation?user={email} before making entity calls.
  8. Ensure TLS 1.2 is used for all inbound connections.

Required scopes

Scope Description Required for
API User (system) security level Provides full system administrator access to Autotask modules, features, and data via the REST API with no UI access. No per-seat charge; no limit on number of API-only users. All REST API access
Create Company Webhooks permission Must be explicitly enabled on the API user's security level under the 'Other' tab. Disabled by default for all security levels. Creating and managing webhooks
Impersonation permission Must be enabled on both the API-only user's security level and the impersonated resource's security level to attribute actions to a specific user. ImpersonationResourceId header usage

User object / data model

Field Type Description On create On update Notes
id integer System-assigned unique identifier for the resource. read-only (system-set; do not supply) read-only Attempting to set id on POST will cause the create to fail.
firstName string(50) Resource's first name. required optional
lastName string(50) Resource's last name. required optional
email string(254) Primary email address. Max 254 characters enforced by the API. required optional Also email2 and email3 fields available; same 254-char limit applies.
userName string(254) Login username for the resource. required read-only after creation
password string Resource login password. Never returned on query (always null). required optional (set to new value to change) If strong password policy is enabled: min 7 chars, at least one special character in positions 2-6, must differ from previous 5 passwords.
securityLevelID integer (picklist) References the security level assigned to the resource. required optional Use GET /SecurityLevels to retrieve valid picklist values.
licenseType integer (picklist) License type assigned to the resource (e.g., Full, Limited, API-only). required optional
isActive boolean Indicates whether the resource account is active. optional (defaults to true) optional
phone string(25) Primary phone number. optional optional
mobilePhone string(25) Mobile phone number. optional optional
title string(50) Job title of the resource. optional optional
departmentID integer (reference) References the department the resource belongs to. optional optional
locationID integer (reference) References the office location of the resource. optional optional
defaultServiceDeskRoleID integer (reference) Default service desk role assigned to the resource. optional optional
internalCost decimal Internal cost rate for the resource. optional optional If the date range for Internal Cost does not include the current date, value is returned as 0.
hireDate datetime (UTC) Date the resource was hired. optional optional All datetime fields stored and returned in UTC.
userDefinedFields array of {Name, value} Customer-specific user-defined fields attached to the resource. optional optional UDF names and values vary per Autotask implementation. Query /Resources/entityInformation/fields to discover available UDFs.

Core endpoints

Get Resource by ID

  • Method: GET
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/Resources/{id}
  • Watch out for: Returns a single item object (not an items array). A 404 is returned if the ID does not exist.

Request example

GET /V1.0/Resources/29683995
Headers:
  UserName: apiuser@example.com
  Secret: abc123
  ApiIntegrationCode: ASHJKLFDKAHKASLFH85LSA905H
  Content-Type: application/json

Response example

{
  "item": {
    "id": 29683995,
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "isActive": true,
    "userDefinedFields": []
  }
}

Query Resources (filter)

  • Method: POST
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/Resources/query
  • Watch out for: GET query strings are limited to 2048 characters; use POST for complex filters. Max 500 records per page.

Request example

POST /V1.0/Resources/query
{
  "filter": [
    {"op": "eq", "field": "isActive", "value": true}
  ],
  "MaxRecords": 500
}

Response example

{
  "items": [{"id": 29683995, "firstName": "Jane", ...}],
  "pageDetails": {
    "count": 1,
    "requestCount": 500,
    "prevPageUrl": null,
    "nextPageUrl": null
  }
}

Create Resource

  • Method: POST
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/Resources
  • Watch out for: Do not include 'id' in the POST body - the create will fail. Password is never returned on subsequent queries.

Request example

POST /V1.0/Resources
{
  "firstName": "John",
  "lastName": "Smith",
  "email": "john@example.com",
  "userName": "john@example.com",
  "password": "P@ssw0rd!",
  "securityLevelID": 1,
  "licenseType": 1,
  "isActive": true
}

Response example

{
  "itemId": 29684100
}

Update Resource (partial)

  • Method: PATCH
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/Resources
  • Watch out for: PATCH only updates supplied fields. Read-only fields are silently ignored. 'id' must be included in the body.

Request example

PATCH /V1.0/Resources
{
  "id": 29684100,
  "isActive": false,
  "title": "Senior Engineer"
}

Response example

{
  "itemId": 29684100
}

Replace Resource (full)

  • Method: PUT
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/Resources
  • Watch out for: PUT replaces the full entity. Omitting optional fields may clear existing values.

Request example

PUT /V1.0/Resources
{
  "id": 29684100,
  "firstName": "John",
  "lastName": "Smith",
  "email": "john@example.com",
  "isActive": true
}

Response example

{
  "itemId": 29684100
}

Get Resource Field Metadata

  • Method: GET
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/Resources/entityInformation/fields
  • Watch out for: Use this endpoint to discover picklist values, UDF definitions, and field constraints specific to your Autotask instance - they vary per implementation.

Request example

GET /V1.0/Resources/entityInformation/fields

Response example

{
  "fields": [
    {"name": "firstName", "dataType": "string",
     "isRequired": true, "isReadOnly": false, ...}
  ]
}

Get Zone Information

  • Method: GET
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/zoneInformation?user={email}
  • Watch out for: Must be the first call made to determine the correct zone-specific base URL. All subsequent calls must use the returned zone URL.

Request example

GET /V1.0/zoneInformation?user=apiuser@example.com

Response example

{
  "url": "https://webservices4.autotask.net/",
  "webUrl": "https://ww4.autotask.net/",
  "zoneId": 4
}

Create Company Webhook (for user-change events)

  • Method: POST
  • URL: https://webservices[n].autotask.net/ATServicesRest/V1.0/CompanyWebhooks
  • Watch out for: Webhook creation permission is disabled by default on all security levels. Must be explicitly enabled on the API user's security level under the 'Other' tab. Webhooks only fire if the webhook owner has the required entity permissions.

Request example

POST /V1.0/CompanyWebhooks
{
  "IsActive": true,
  "Name": "myapp.Resources.Modify",
  "WebhookUrl": "https://myapp.example.com/hook",
  "DeactivationUrl": "https://myapp.example.com/deactivate",
  "IsSubscribedToUpdateEvents": true,
  "SecretKey": "mysecret123"
}

Response example

{
  "itemId": 5
}

Rate limits, pagination, and events

  • Rate limits: Autotask enforces a limit of 10,000 API requests per rolling 60-minute window per database (counting all integrations combined). A usage-based latency is added as usage approaches the threshold (e.g., 0.5s latency at 50% usage, 1s at 75%). A 5-minute execution timeout applies to all REST API calls. Thread limits also apply per object endpoint per tracking identifier (default 3 threads for integrations created after 2023.1).
  • Rate-limit headers: No
  • Retry-After header: No
  • Rate-limit notes: Threshold applies across all integrations sharing the same Autotask database. Exceeding the limit suspends API access for the entire tenant. Autotask sends email notifications when the threshold is exceeded. Use the 'API Activity by Hour' report in Autotask to monitor usage. Call batching is not available for the REST API.
  • Pagination method: cursor
  • Default page size: 500
  • Max page size: 500
  • Pagination pointer: MaxRecords (in search body); nextPageUrl / prevPageUrl returned in pageDetails
Plan Limit Concurrent
All plans (per database) 10,000 requests per rolling 60-minute window 3
  • Webhooks available: Yes
  • Webhook notes: Autotask supports outbound webhooks created and managed entirely via the REST or SOAP API. Webhooks fire an HTTP POST to a registered URL when a subscribed event occurs. Callouts typically fire within one minute of a trigger event; up to five minutes under heavy load.
  • Alternative event strategy: Poll the Resources or Contacts endpoints using LastModifiedDate filters to detect changes without webhooks. Webhooks are the preferred approach as they reduce API call volume.
  • Webhook events: Create (entity record created), Update/PATCH (subscribed field or UDF changed), PUT (full entity update), Delete (entity record deleted), Deactivate (webhook callout deactivated)

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: N/A - No native SCIM endpoint in Autotask PSA. SCIM provisioning is available only via third-party IdP integrations (e.g., Okta SCIM connector to Autotask).
  • Endpoint: Not documented

Limitations:

  • No native SCIM 2.0 endpoint exposed by Autotask PSA.
  • SCIM-like provisioning requires an Okta integration or similar IdP connector that maps SCIM calls to Autotask REST API calls.
  • The Autotask REST API does not support SSO authentication; API credentials are separate from SSO credentials.

Common scenarios

Three core automation scenarios are well-supported by the API:

  • Provision: POST /Resources with required fields (firstName, lastName, email, userName, password, securityLevelID, licenseType, isActive=true). Do not include 'id' in the body-it causes the request to fail. Fetch picklist values for securityLevelID from GET /Resources/entityInformation/fields first, as values are instance-specific.
  • Deprovision: PATCH /Resources with {"id": , "isActive": false}. There is no DELETE operation on the Resources entity; deactivation is the only supported offboarding path via the API.
  • Real-time sync: POST /CompanyWebhooks to register a callout URL, then POST /CompanyWebhookFields to specify which field changes trigger it. Webhooks fire within one minute under normal load. Note: webhook creation permission is disabled by default on all security levels and must be explicitly granted.

Provision a new internal user (Resource)

  1. Call GET /zoneInformation?user={adminEmail} to resolve the correct zone-specific base URL.
  2. Call GET /Resources/entityInformation/fields to discover required fields, picklist values for securityLevelID and licenseType specific to the instance.
  3. Call POST /Resources with firstName, lastName, email, userName, password, securityLevelID, licenseType, and isActive=true.
  4. Store the returned itemId as the resource's Autotask ID for future updates.
  5. Optionally call PATCH /Resources with the new id to set additional fields (title, departmentID, etc.).

Watch out for: Do not include 'id' in the POST body. Password must meet strong-password policy if enabled (min 7 chars, special character in positions 2-6, not one of last 5 passwords). Picklist values for securityLevelID must be fetched from the target instance - they are not universal.

Deprovision / deactivate a user

  1. Query POST /Resources/query with a filter on email or userName to retrieve the resource's id.
  2. Call PATCH /Resources with {"id": , "isActive": false} to deactivate the account.
  3. Optionally verify deactivation by calling GET /Resources/{id} and confirming isActive is false.

Watch out for: There is no DELETE operation on the Resources entity - deactivation via isActive=false is the correct offboarding method. Deleting a resource is not supported via the REST API.

Sync user changes in near-real-time using webhooks

  1. Ensure the API user's security level has 'Create Company Webhooks' permission enabled (Admin > Security Levels > Other tab).
  2. Call POST /CompanyWebhooks (or the relevant entity webhook endpoint) with WebhookUrl, DeactivationUrl, IsActive=true, and the desired event subscriptions (IsSubscribedToUpdateEvents, etc.).
  3. Register WebhookFields via POST /CompanyWebhookFields to specify which field changes trigger the callout.
  4. Receive HTTP POST payloads at the registered WebhookUrl when subscribed events occur (typically within 1 minute).
  5. Use the payload's entity data to update the external system; use ExcludedResources to suppress callouts triggered by the integration's own writes.

Watch out for: Webhooks only fire if the webhook owner (API user) has entity-level and Line of Business permissions for the records involved. If the owner lacks access to a record, the callout will not fire for that record. Webhook creation permission is off by default - it must be explicitly granted per security level.

Why building this yourself is a trap

The rate limit is per database, not per integration: all integrations sharing the same Autotask tenant draw from a single pool of 10,000 requests per rolling 60-minute window. One poorly throttled integration can degrade every other connected system in the tenant.

Additional constraints compound this: a hard cap of 500 records per query page, a 3-thread-per-endpoint default for integrations created after 2023.1, and a 5-minute execution timeout on all REST calls.

Webhooks mitigate call volume but introduce their own caveat-callouts only fire for records the webhook-owning API user has permission to access, so a misconfigured security level silently drops events without error.

Automate Autotask PSA 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

UpdatedFeb 27, 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