Meta System User Access Token: Setup, Limits, Expiry
A Meta system user access token belongs to a system user in your business portfolio, not a person. Create the system user in Business Settings or with POST /{business_id}/system_users, assign it ad accounts and Pages, install your app, then generate the token. It never expires by default, or lasts 60 days if you opt in. Limited Access allows 1 system user; Full Access, 10.
A Meta system user access token is an access token that belongs to a system user: an account in your Meta business portfolio that represents software, not a person. You create the system user, assign it the ad accounts and Pages it may touch, install your app on it, and generate the token. By default the token never expires, which is why server jobs and ad automation use it.
This guide covers both routes, through Business Settings and through the API, plus the limits and expiry rules. It's part of our Meta Ads API series.
What is a Meta system user?
A Meta system user is a non-human account in a business portfolio that your server uses to call the Marketing API. Meta's access token guide says system user tokens "let your app perform programmatic, automated actions on Ad objects or Pages."
Meta has two kinds, per its system users overview:
| Admin system user | System user | |
|---|---|---|
| API role value | ADMIN |
EMPLOYEE |
| Can create system users and ad accounts | Yes | No |
| Asset access | All assets the portfolio owns or has been shared, by default | Only assets assigned to it |
| Limit per business | 1 | 1 on Limited Access, 10 on Full Access |
Meta's advice is to create one system user per type of access you need, so a leaked token reaches only what that job needs.
Why do platforms use system users?
Platforms use Meta system users because the token survives staff changes. A user access token stops working when that person changes their password, leaves, or removes the app. A system user token has no person behind it, and Meta's authentication guide says system user tokens are "useful for server-to-server interactions where there is no user present to authenticate."
The catch is scope. A system user only reaches assets in your business portfolio or shared with it. To manage a customer's ad account through a system user, the customer has to share that account with your business first. A platform with many self-serve customers usually takes a user token from each one through Facebook Login instead. Our Meta Ads API access token guide compares the two.
What do you need before you start?
- A business portfolio where you are an admin.
- A Meta app that belongs to the same portfolio. Meta's create guide says a system user can only get a role on an app owned by the same business.
- App Review for the permissions the system user needs, such as
ads_management. Meta's overview says the app needs Marketing API access and must have passed app review. - Live mode, if you want the higher system user limit.
Step 1: Create the system user
In Meta Business Suite, open Settings, then Users, then System users, and click Add. Give it a name, choose Admin or Employee, and save.
To do it by API, call the business's system_users edge with an admin user's token:
curl -X POST "https://graph.facebook.com/v26.0/$BUSINESS_ID/system_users" \
-F "name=Ad Server" \
-F "role=EMPLOYEE" \
-F "access_token=$ADMIN_TOKEN"The response is an app-scoped id. Meta says to use that ID in API calls, not the one shown in Business Settings.
Step 2: Assign ad accounts and Pages
Assign every asset the system user will call, before you generate the token. In Business Settings, click the system user's name, choose Assign assets, pick the ad accounts and Pages, and set the access level.
By API, add the system user to an ad account's assigned_users with the tasks it needs:
curl -X POST "https://graph.facebook.com/v26.0/act_$AD_ACCOUNT_ID/assigned_users" \
-F "user=$SYSTEM_USER_ID" \
-F 'tasks=["MANAGE","ADVERTISE","ANALYZE"]' \
-F "access_token=$ADMIN_TOKEN"Meta's assigned users reference lists MANAGE, ADVERTISE, ANALYZE, DRAFT, and AA_ANALYZE. Grant the smallest set the job needs. A reporting job needs ANALYZE, not MANAGE.
Step 3: Install the app and generate the token
The system user has to install your app, and then you generate a token for that app with the scopes you want. Meta's token guide covers both calls.
Install the app:
curl -X POST "https://graph.facebook.com/v26.0/$SYSTEM_USER_ID/applications" \
-F "business_app=$APP_ID" \
-F "access_token=$ADMIN_TOKEN"Generate the token:
curl -X POST "https://graph.facebook.com/v26.0/$SYSTEM_USER_ID/access_tokens" \
-F "business_app=$APP_ID" \
-F "scope=ads_management,business_management" \
-F "appsecret_proof=$APPSECRET_PROOF" \
-F "set_token_expires_in_60_days=true" \
-F "access_token=$ADMIN_TOKEN"appsecret_proof is an HMAC-SHA256 of the access token, keyed with your App Secret. In Business Settings, the same step is Generate new token: pick the app, tick the permissions, and copy the token. Meta's Managed Partner Ads guide warns: "Make sure to copy the generated token as you won't be able to access it again."
Does a Meta system user access token expire?
A Meta system user access token never expires unless you ask for a 60-day token. Meta's token guide describes both options:
| Option | How to get it | Lifetime | Refresh |
|---|---|---|---|
| Non-expiring | Omit set_token_expires_in_60_days |
No expiry | Can't be refreshed |
| Expiring | set_token_expires_in_60_days=true |
60 days from generation or last refresh | Refresh before day 60 or the token is forfeited |
Meta treats expiring tokens as the safer choice, and some businesses are required to use them. For those businesses, omitting the parameter returns an error. Build the refresh job from the start so you don't have to add it during an incident.
A non-expiring token can still be invalidated. Meta's access token guide says even long-lived tokens are "still subject to invalidation for other reasons." To revoke one, send a DELETE to /{system-user-id}/access_tokens.
How many system users can I create?
The Meta system user limit depends on your app's Marketing API Access Tier: 1 system user on Limited Access and 10 on Full Access, plus 1 admin system user either way. Meta's authorization guide lists both.
Meta renamed the tiers on May 4, 2026. "Ads Management Standard Access" became the Marketing API Access Tier, and Standard and Advanced became Limited and Full. Some Meta pages still use the old labels. In the announcement, Jiaqi Sun wrote that Full Access:
"unlocks higher Marketing API rate limits, system user quotas, and other enhanced capabilities for your app."
To qualify, Meta asks for 500 or more Marketing API calls in the past 15 days and an error rate under 15% on the last 500. The rate limits that come with each tier are in our Meta Marketing API rate limit guide.
Is there a simpler route for customer ad accounts?
For customers' ad accounts, Adeli works from each customer's own Facebook connection instead of a system user in your portfolio. Your customer authorizes through Facebook Login for Business, and Adeli's Ads endpoints act within that connection: list ad accounts, read the campaign tree, pull insights, set status, and read leads.
- No asset sharing. List ad accounts returns every ad account the connection can reach, both directly assigned and owned by a business portfolio the authorizing person administers.
- Roles still apply. Meta's access tier and the person's ad-account role still apply on top of Adeli's grants.
That fits vertical SaaS and AI marketing platforms where each customer brings their own ad account, through the same Facebook connection described on the Facebook API page. Keep system users for jobs on your own business's assets.