Stitchflow
Meta Ads logo

Meta Ads 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

The Meta Marketing API (Graph API v20.0, base URL https://graph.facebook.com/v20.0) exposes full CRUD over Business Manager membership and asset-level ad account assignments.

Authentication is OAuth 2.0;

for server-to-server automation, System User Access Tokens are strongly preferred over User Access Tokens because they can be set to non-expiring, avoiding the ~60-day expiry that breaks unattended workflows.

The business_management and ads_management scopes require Meta App Review before use with users outside your own Business Manager - plan for this gate in any production timeline.

Integrating Meta Ads into an identity graph requires reconciling two separate user namespaces: business_user IDs (active members) and pending_user IDs (unaccepted invitations), which are distinct identifiers returned from different endpoints and must not be mixed.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (User Access Token or System User Access Token)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredFree (via Meta Work Accounts / Workplace)

Authentication

Auth method: OAuth 2.0 (User Access Token or System User Access Token)

Setup steps

  1. Create a Meta App at developers.facebook.com and add the Marketing API product.
  2. Request the required permissions (scopes) via App Review if targeting users outside your own Business Manager.
  3. Generate a User Access Token via OAuth 2.0 authorization flow, or create a System User in Business Manager and generate a System User Access Token for server-to-server use.
  4. Pass the access token as the 'access_token' query parameter or in the Authorization header on all API requests.

Required scopes

Scope Description Required for
ads_management Read and manage ad accounts, campaigns, ad sets, and ads. Full ad account management operations
ads_read Read-only access to ad account data and insights. Reading ad account and campaign data without write access
business_management Manage Business Manager assets including users, pages, and ad accounts. Adding/removing users from Business Manager and assigning roles
read_insights Read ad performance insights and reporting data. Accessing Insights API endpoints

User object / data model

Field Type Description On create On update Notes
id string Unique Meta user ID. system-assigned immutable Returned on all user nodes.
name string Full name of the user. read from Meta profile not updatable via API Pulled from the user's personal Meta account.
email string Email address of the user. read from Meta profile not updatable via API Requires email permission; may not be returned for all users.
role enum Role of the user within the Business Manager (ADMIN, EMPLOYEE, etc.). required updatable Values: ADMIN, EMPLOYEE. Asset-level roles differ (e.g., ADVERTISER, ANALYST on ad accounts).
status enum Invitation or membership status (ACTIVE, PENDING). system-assigned read-only PENDING until the invited user accepts.
finance_permission enum Finance role on the business (NONE, EDITOR, ANALYST). optional updatable Controls access to billing and payment methods.
ip_permission enum IP/catalog permission level. optional updatable Relevant for catalog and IP asset access.
tasks array List of tasks the user can perform on a specific asset (e.g., ADVERTISE, ANALYZE, MANAGE). required when assigning to asset updatable Used when assigning users to ad accounts or pages, not at the Business level.
created_time datetime Timestamp when the user was added to the business. system-assigned immutable ISO 8601 format.

Core endpoints

List Business Users

  • Method: GET
  • URL: https://graph.facebook.com/v20.0/{business-id}/business_users
  • Watch out for: Requires business_management permission. Only returns users who have accepted their invitation (ACTIVE). Pending invitations appear under /pending_users.

Request example

GET /v20.0/{business-id}/business_users?fields=id,name,email,role,status&access_token={token}

Response example

{
  "data": [
    {"id":"123","name":"Jane Doe","role":"ADMIN","status":"ACTIVE"}
  ],
  "paging": {"cursors":{"before":"abc","after":"xyz"}}
}

List Pending Users

  • Method: GET
  • URL: https://graph.facebook.com/v20.0/{business-id}/pending_users
  • Watch out for: Pending users have a different node type and ID than active business_users. Do not mix IDs between the two endpoints.

Request example

GET /v20.0/{business-id}/pending_users?fields=id,email,role&access_token={token}

Response example

{
  "data": [
    {"id":"456","email":"new@example.com","role":"EMPLOYEE"}
  ]
}

Invite User to Business

  • Method: POST
  • URL: https://graph.facebook.com/v20.0/{business-id}/business_users
  • Watch out for: Sends an email invitation; user must accept before becoming ACTIVE. The returned ID is the pending_user ID, not the final business_user ID.

Request example

POST /v20.0/{business-id}/business_users
{
  "email": "user@example.com",
  "role": "EMPLOYEE"
}

Response example

{
  "id": "789",
  "email": "user@example.com",
  "status": "PENDING"
}

Update Business User Role

  • Method: POST
  • URL: https://graph.facebook.com/v20.0/{business-id}/business_users
  • Watch out for: Role updates use POST (not PATCH) to the same endpoint. Requires the caller to be a Business Admin.

Request example

POST /v20.0/{business-id}/business_users
{
  "user": "{user-id}",
  "role": "ADMIN"
}

Response example

{
  "success": true
}

Remove User from Business

  • Method: DELETE
  • URL: https://graph.facebook.com/v20.0/{business-id}/business_users
  • Watch out for: Removes the user from the Business Manager entirely, including all asset access. This action is irreversible via API.

Request example

DELETE /v20.0/{business-id}/business_users?user={user-id}&access_token={token}

Response example

{
  "success": true
}

Assign User to Ad Account

  • Method: POST
  • URL: https://graph.facebook.com/v20.0/{business-id}/client_ad_accounts
  • Watch out for: Tasks array controls granular permissions on the ad account. Valid tasks: MANAGE, ADVERTISE, ANALYZE, DRAFT. User must already be a Business Member.

Request example

POST /v20.0/act_{ad-account-id}/assigned_users
{
  "user": "{user-id}",
  "tasks": ["ADVERTISE","ANALYZE"]
}

Response example

{
  "success": true
}

List Users Assigned to Ad Account

  • Method: GET
  • URL: https://graph.facebook.com/v20.0/act_{ad-account-id}/assigned_users
  • Watch out for: Ad account IDs must be prefixed with 'act_' (e.g., act_123456789).

Request example

GET /v20.0/act_{ad-account-id}/assigned_users?fields=id,name,tasks&access_token={token}

Response example

{
  "data": [
    {"id":"123","name":"Jane Doe","tasks":["ADVERTISE","ANALYZE"]}
  ]
}

Remove User from Ad Account

  • Method: DELETE
  • URL: https://graph.facebook.com/v20.0/act_{ad-account-id}/assigned_users
  • Watch out for: Removes asset-level access only; does not remove the user from the Business Manager.

Request example

DELETE /v20.0/act_{ad-account-id}/assigned_users?user={user-id}&access_token={token}

Response example

{
  "success": true
}

Rate limits, pagination, and events

  • Rate limits: Meta Marketing API uses Business Use Case (BUC) rate limiting. Each API call consumes a score based on complexity. Limits are per app per ad account. The API returns rate limit usage in response headers.
  • Rate-limit headers: Yes
  • Retry-After header: No
  • Rate-limit notes: Rate limit usage is returned in the 'X-Business-Use-Case-Usage' response header (JSON-encoded). When throttled, the API returns error code 17 or 80000/80003. Docs do not explicitly document a Retry-After header; back-off strategy is recommended.
  • Pagination method: cursor
  • Default page size: 25
  • Max page size: 100
  • Pagination pointer: after / before (cursor), limit
Plan Limit Concurrent
Development Access Lower call volume; restricted to app users only 0
Standard Access Higher BUC score allowance; granted after App Review 0
  • Webhooks available: No
  • Webhook notes: Meta does not offer webhooks specifically for Business Manager user-management events (user added, role changed, removed). Meta Webhooks exist for other objects (Pages, Instagram, WhatsApp) but not for ad account or business user lifecycle events.
  • Alternative event strategy: Poll the /business_users and /pending_users endpoints periodically to detect membership changes.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Free (via Meta Work Accounts / Workplace)

  • Endpoint: https://www.facebook.com/scim/v2/

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

Limitations:

  • SCIM provisioning applies to Meta Work Accounts (formerly Workplace by Meta), not directly to Meta Ads Business Manager user roles or ad account task assignments.
  • SCIM does not provision ad account-level task permissions (ADVERTISE, ANALYZE, etc.); those must be managed via the Graph API.
  • No major IdP (Okta, Entra, Google Workspace, OneLogin) has a pre-built Meta Ads SCIM connector listed in their official app catalogs as of the research date.
  • SCIM token is generated within the Workplace/Work Accounts admin console, not via the Marketing API OAuth flow.
  • Group provisioning support via SCIM is limited; check current Workplace SCIM documentation for group object support.

Common scenarios

Three automation scenarios cover the majority of lifecycle operations.

Onboarding: POST to /{business-id}/business_users to invite, poll /pending_users until acceptance, then re-fetch /business_users to obtain the final business_user ID before POSTing to /act_{ad-account-id}/assigned_users with the appropriate tasks array (MANAGE, ADVERTISE, ANALYZE, or DRAFT).

The ID change between pending and active state is a hard requirement - using the pending_user ID for asset assignment will fail.

Offboarding: DELETE to /{business-id}/business_users removes the user from the Business Manager and cascades revocation across all assigned assets in that business;

no per-asset DELETE calls are needed, but the action is irreversible via API.

Auditing: GET /business_users with fields=id,name,email,role,status for the membership list, then GET /act_{ad-account-id}/assigned_users with fields=id,name,tasks per ad account;

cross-reference to produce a full user-to-asset access matrix.

All three scenarios require cursor-based pagination (after/before params, default page size 25, max 100) - incomplete pagination is the most common cause of audit gaps in large Business Managers.

Onboard a new advertiser to a Business Manager and Ad Account

  1. POST /v20.0/{business-id}/business_users with email and role=EMPLOYEE to send an invitation.
  2. Wait for the user to accept the invitation (poll GET /v20.0/{business-id}/pending_users until the user no longer appears, then confirm via GET /v20.0/{business-id}/business_users).
  3. Once ACTIVE, POST to /v20.0/act_{ad-account-id}/assigned_users with the user ID and tasks=["ADVERTISE","ANALYZE"] to grant ad account access.

Watch out for: The user ID changes between the pending_user stage and the active business_user stage. Re-fetch the user list after acceptance to get the correct business_user ID before assigning to assets.

Revoke all access for a departing employee

  1. GET /v20.0/{business-id}/business_users to retrieve the user's business_user ID.
  2. DELETE /v20.0/{business-id}/business_users?user={user-id} to remove the user from the Business Manager.
  3. Verify removal by confirming the user no longer appears in the business_users list.

Watch out for: Removing a user from the Business Manager automatically revokes all asset-level access (ad accounts, pages, etc.) within that business. No need to individually remove from each asset, but this is irreversible via API.

Audit all users and their ad account permissions

  1. GET /v20.0/{business-id}/business_users?fields=id,name,email,role,status to list all active members.
  2. For each ad account, GET /v20.0/act_{ad-account-id}/assigned_users?fields=id,name,tasks to list per-account task assignments.
  3. Cross-reference the two datasets to produce a full access matrix of users vs. ad accounts and their tasks.

Watch out for: Pagination is cursor-based; iterate through all pages using the 'after' cursor before assuming you have a complete list. Large businesses with many users or ad accounts will require many paginated requests.

Why building this yourself is a trap

Several API behaviors create silent failure modes worth flagging explicitly. Rate limiting uses Business Use Case (BUC) scoring returned in the X-Business-Use-Case-Usage response header as a JSON-encoded object - not a simple integer - and must be parsed before back-off logic can act on it; error codes 17, 80000, and 80003 indicate throttling.

Meta deprecates API versions on a rolling ~2-year schedule, so hardcoding /v20.0/ in all request URLs is required to avoid silent fallback to the oldest supported version. SCIM 2.0 is available (endpoint: https://www.facebook.com/scim/v2/) but scoped to Meta Work Accounts (formerly Workplace), not to Business Manager ad account roles or task assignments;

SCIM provisioning does not populate the tasks array on ad accounts, meaning a separate Graph API integration is mandatory for any identity graph that needs to reflect actual ad account permissions.

No major IdP has a pre-built Meta Ads SCIM connector in their official catalog, and no webhook events exist for Business Manager user lifecycle changes - membership state must be tracked by polling /business_users and /pending_users on a defined schedule.

Automate Meta Ads 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