Stitchflow
ActiveCampaign logo

ActiveCampaign User Management API Guide

API workflow

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

UpdatedFeb 25, 2026

Summary and recommendation

ActiveCampaign's REST API (v3, base URL: `https://{youraccountname}.api-us1.com/api/3`) supports full user lifecycle management: create, read, update, and delete users, plus group retrieval and assignment. Authentication is via a per-user API key passed as the `Api-Token` HTTP header - there is no account-level default key.

The rate limit is 5 requests per second, account-wide and shared across all API keys on the account. Pagination uses offset/limit (default 20, max 100); the users list endpoint does not reliably return a `meta.total` count, so callers must iterate until an empty array is returned.

There is no native SCIM 2.0 support on any plan. For teams managing ActiveCampaign alongside a broader SaaS portfolio, Stitchflow's MCP server with ~100 deep IT/identity integrations provides a structured alternative to building and maintaining tailored polling logic against this API.

API quick reference

Has user APIYes
Auth methodAPI Key (Http Header)
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredEnterprise

Authentication

Auth method: API Key (Http Header)

Setup steps

  1. Log in to your ActiveCampaign account.
  2. Click the Settings gear icon in the left sidebar.
  3. Click 'Developer' in the Account Settings menu.
  4. Copy the API URL (your base URL) and the API Key.
  5. Pass the key on every request as the HTTP header: Api-Token: .

User object / data model

Field Type Description On create On update Notes
id string Auto-assigned unique user ID. read-only (returned) read-only Use in URL path for GET/PUT/DELETE /users/{id}.
username string Unique login username for the user. required read-only (cannot be changed after creation) Must be unique across the account.
email string User's email address. required optional Used for login and notifications.
firstName string User's first name. required optional
lastName string User's last name. required optional
password string User's account password. required optional Write-only; never returned in responses.
group integer ID of the permission group to assign the user to. required optional Permissions in ActiveCampaign are set at the group level, not the user level.
phone string User's phone number. optional optional
signature string|null User's email signature. optional optional Returned as null if not set.
lang string User's language preference (e.g., 'english'). optional optional Returned in create response; not always present in list response.
localZoneid string User's timezone (e.g., 'America/New_York'). optional optional IANA timezone string.
userGroup string ID of the user's current group (returned in update response). read-only (derived from group param) read-only (derived from group param) Linked resource; see links.userGroup for full object URL.
cdate string (ISO 8601) Date/time the user was created. read-only (returned) read-only
udate string (ISO 8601) Date/time the user was last updated. read-only (returned) read-only
links object Hypermedia links to related resources (lists, userGroup, dealGroupTotals, dealGroupUsers, configs). read-only (returned) read-only Use these URLs to fetch related sub-resources.

Core endpoints

Create a user

  • Method: POST
  • URL: https://{youraccountname}.api-us1.com/api/3/users
  • Watch out for: A paid user seat must be available on the account before a new user can be created. Creating a user does not automatically send an invitation email.

Request example

{
  "user": {
    "username": "jdoe",
    "firstName": "John",
    "lastName": "Doe",
    "email": "jdoe@example.com",
    "password": "myPa$$w0rd",
    "group": 4
  }
}

Response example

{
  "user": {
    "id": "3",
    "username": "jdoe",
    "email": "jdoe@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "lang": "english",
    "localZoneid": "America/New_York",
    "cdate": "2022-02-02T16:01:44-06:00"
  }
}

List all users

  • Method: GET
  • URL: https://{youraccountname}.api-us1.com/api/3/users
  • Watch out for: Response does not include a meta.total field for users - iterate with offset until an empty array is returned.

Request example

GET /api/3/users?limit=20&offset=0
Header: Api-Token: <key>

Response example

{
  "users": [
    {
      "id": "1",
      "username": "admin",
      "firstName": "John",
      "lastName": "Doe",
      "email": "admin@example.com",
      "phone": "",
      "signature": null
    }
  ]
}

Retrieve a user

  • Method: GET
  • URL: https://{youraccountname}.api-us1.com/api/3/users/{id}
  • Watch out for: Use GET /api/3/users/me to retrieve the currently authenticated user without knowing their ID.

Request example

GET /api/3/users/1
Header: Api-Token: <key>

Response example

{
  "user": {
    "id": "1",
    "username": "admin",
    "firstName": "John",
    "lastName": "Doe",
    "email": "admin@example.com",
    "phone": "",
    "signature": null
  }
}

Retrieve the authenticated user (self)

  • Method: GET
  • URL: https://{youraccountname}.api-us1.com/api/3/users/me
  • Watch out for: Useful for validating API key ownership and resolving the caller's user ID.

Request example

GET /api/3/users/me
Header: Api-Token: <key>

Response example

{
  "user": {
    "id": "1",
    "username": "admin",
    "email": "admin@example.com"
  }
}

Update a user

  • Method: PUT
  • URL: https://{youraccountname}.api-us1.com/api/3/users/{id}
  • Watch out for: username cannot be changed after creation. Full PUT - omitting optional fields may clear them.

Request example

{
  "user": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "jdoe2@example.com",
    "password": "newPa$$w0rd",
    "group": 3
  }
}

Response example

{
  "user": {
    "id": "3",
    "username": "user",
    "email": "jdoe2@example.com",
    "userGroup": "3"
  }
}

Delete a user

  • Method: DELETE
  • URL: https://{youraccountname}.api-us1.com/api/3/users/{id}
  • Watch out for: Deleting a user who owns lists, deals, accounts, or tasks requires reassigning those resources first. Deleting a user whose API key is used in integrations will break those integrations immediately - there is no account-default API key.

Request example

DELETE /api/3/users/3
Header: Api-Token: <key>

Response example

HTTP 200 OK
{}

List all user groups

  • Method: GET
  • URL: https://{youraccountname}.api-us1.com/api/3/groups
  • Watch out for: Permissions are managed at the group level. Retrieve group IDs here before assigning users.

Request example

GET /api/3/groups?limit=20&offset=0
Header: Api-Token: <key>

Response example

{
  "groups": [
    { "id": "1", "title": "Admin", "descript": "" },
    { "id": "2", "title": "Marketing" }
  ]
}

Retrieve a user's group

  • Method: GET
  • URL: https://{youraccountname}.api-us1.com/api/3/users/{id}/userGroup
  • Watch out for: A user belongs to exactly one group. Use PUT /users/{id} with a new group value to reassign.

Request example

GET /api/3/users/3/userGroup
Header: Api-Token: <key>

Response example

{
  "userGroup": {
    "userid": "3",
    "groupid": "2",
    "id": "3"
  }
}

Rate limits, pagination, and events

  • Rate limits: 5 requests per second per account on all hosted plans. No documented daily cap. Exceeding the limit results in throttling (HTTP 429). Custom rate limit solutions available by contacting ActiveCampaign.
  • Rate-limit headers: No
  • Retry-After header: No
  • Rate-limit notes: HTTP 429 is returned when the rate limit is exceeded. No official Retry-After header documented. Implement exponential backoff. Each user's API key shares the same account-level bucket.
  • Pagination method: offset
  • Default page size: 20
  • Max page size: 100
  • Pagination pointer: limit / offset
Plan Limit Concurrent
All hosted plans (Starter, Plus, Pro, Enterprise) 5 requests/second 0
Custom (contact sales) Negotiated 0
  • Webhooks available: Yes
  • Webhook notes: ActiveCampaign supports outbound webhooks that fire on contact and deal activity events. Webhooks are managed via the API (POST/GET/PUT/DELETE /api/3/webhooks). Delivery is guaranteed at-least-once; webhooks are never retried on failure. A webhook is automatically deactivated if the receiving endpoint returns HTTP 410.
  • Alternative event strategy: No native webhook events exist for account-user lifecycle actions (user created, user deleted, user role changed). Poll GET /api/3/users on a schedule to detect changes, or use SSO JIT provisioning for onboarding.
  • Webhook events: subscribe, unsubscribe, update, bounce, click, open, forward, reply, sent, share, contact_tag_added, contact_tag_removed, subscriber_note, list_add, deal_add, deal_update, deal_note_add, deal_pipeline_add, deal_stage_add, deal_task_add, deal_task_complete, deal_tasktype_add, sms_sent, sms_reply, sms_unsub

SCIM API status

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

Limitations:

  • No native SCIM 2.0 support.
  • SSO (SAML) is available on Enterprise plans with Okta and Microsoft Entra ID.
  • User provisioning on first SSO login is handled via JIT (Just-In-Time) provisioning only.
  • New SSO users are added to a configurable 'SSO Users' permission group.
  • No automatic deprovisioning - users must be deleted manually via the UI or DELETE /api/3/users/{id}.
  • No SCIM-based group/role sync.

Common scenarios

Three core automation scenarios are supported by the API. Provisioning: verify seat availability, retrieve group IDs via GET /api/3/groups, then POST /api/3/users with username, email, firstName, lastName, password, and group.

note that username is immutable after creation and no invite email is sent automatically.

Deprovisioning: locate the user via GET /api/3/users, reassign any owned lists, deals, accounts, or tasks (the delete will fail if owned resources are not reassigned first), rotate any integrations using that user's API key to a different key, then DELETE /api/3/users/{id}.

the purchased seat count is not reduced by deletion and requires a separate Billing & Upgrade action. Directory sync: paginate `GET /api/3/users?

limit=100&offset=0`, incrementing offset until an empty array is returned, diff against your directory, and POST or DELETE accordingly on a scheduled poll - no user-lifecycle webhook events exist, so polling is the only available sync mechanism.

Provision a new team member

    1. Verify a user seat is available (check Billing & Upgrade page or account plan).
    1. GET /api/3/groups to retrieve available permission group IDs.
    1. POST /api/3/users with username, email, firstName, lastName, password, and group (group ID).
    1. Store the returned user id for future updates or deletion.
    1. Share login credentials with the new user out-of-band (no invite email is sent automatically).

Watch out for: If no seats are available, the POST will fail. Seats must be purchased before provisioning. username cannot be changed later.

Deprovision a departing user

    1. GET /api/3/users to find the user's id by email or username.
    1. Reassign any owned lists, deals, accounts, and tasks to another user via the UI or relevant API endpoints (e.g., PUT /api/3/deals/{id} to change owner).
    1. If the user's API key is used in any integrations, update those integrations with a different user's API key first.
    1. DELETE /api/3/users/{id} to remove the user.
    1. Note: deleting the user does not reduce the number of purchased seats - the seat remains available for reassignment.

Watch out for: Deleting a user whose API key powers active integrations will immediately break those integrations. There is no grace period or account-default fallback key.

Sync user roster to an external directory

    1. GET /api/3/users?limit=100&offset=0 to fetch the first page of users.
    1. Increment offset by 100 and repeat until an empty users array is returned (no meta.total is reliably provided).
    1. Compare the fetched list against your directory to identify additions and removals.
    1. For new users in the directory not in ActiveCampaign, POST /api/3/users to create them.
    1. For users in ActiveCampaign not in the directory, DELETE /api/3/users/{id} after reassigning owned resources.
    1. Schedule this poll at an interval appropriate for your org (e.g., hourly) - no user-lifecycle webhooks exist to trigger real-time sync.

Watch out for: No webhook events exist for user create/update/delete. Polling is the only sync mechanism. Rate limit is 5 req/sec account-wide - batch carefully on large rosters.

Why building this yourself is a trap

Several API behaviors create silent failure modes that are worth flagging explicitly. The per-user API key model means any integration authenticated with a deleted user's key breaks immediately with no grace period and no account-default fallback - this is the highest-severity operational risk in the API.

The account-wide 5 req/sec rate limit is shared across all keys simultaneously; concurrent integrations using different user keys still draw from the same bucket, and HTTP 429 responses carry no Retry-After header, requiring manual exponential backoff implementation.

No webhook events fire on user create, update, or delete, making event-driven sync architecturally impossible without a polling layer. The PUT /api/3/users/{id} endpoint is a full replacement - omitting optional fields may clear existing values.

Finally, SCIM is entirely absent: SSO JIT provisioning (Enterprise only) handles onboarding on first login but provides no deprovisioning signal and no IdP-driven group assignment, leaving offboarding fully dependent on manual API calls or UI actions.

Automate ActiveCampaign workflows without one-off scripts

Stitchflow builds and maintains identity workflows for your exact setup. We cover every app, including the ones without APIs, and run deterministic trigger-to-report workflows with human approvals where they matter.

Every app coverage, including apps without APIs
60+ deep API integrations plus browser automation where needed
Identity 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 25, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

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

Adyen logo

Adyen

API Only
AutomationAPI only
Last updatedFeb 2026

Adyen user management is handled entirely through the Customer Area (Settings > Users) using a predefined role-based access control model. There are no custom roles — all roles are defined by Adyen, and admins can only assign roles they themselves alre

AfterShip logo

AfterShip

API Only
AutomationAPI only
Last updatedFeb 2026

AfterShip uses a role-based access control model with four default roles — Owner, Admin, Manager, and Support Agent — available across all plans. Enterprise customers can additionally configure custom roles with granular permission flags. There is no n