# Meta Ads API Access Token: Which One and How to Get It

How to get a Meta Ads API access token: user token via Facebook Login, long-lived exchange, system user tokens, Page tokens for leads, and debugging expiry.

Canonical page: https://www.tryadeli.com/blog/meta-ads-api-access-token
Last updated: 2026-10-26

By Mika Reyes, Co-founder, Adeli. Published 2026-10-26.

## The short answer

A Meta Ads API access token is either a user access token from Facebook Login or a system user access token from a business portfolio. For customers' ad accounts, request ads_management through Facebook Login, exchange the code on your server, then swap the short-lived token for a long-lived one that lasts about 60 days. Check any token with debug_token.

A Meta Ads API access token is the credential every Marketing API call carries. There are two kinds that work on ad accounts: a **user access token**, which a person grants through Facebook Login, and a **system user access token**, which belongs to a system user in a business portfolio. If your product manages your customers' ad accounts, you want **long-lived user tokens**, one per customer.

This guide shows how to get each token, which permissions to request, and how to tell why a token stopped working. It's part of our [Meta Ads API](https://www.tryadeli.com/blog/meta-ads-api) series.

## Which token does the Meta Ads API use?

**The Meta Ads API accepts a user access token or a system user access token on ad account calls.** Meta's [authentication guide](https://developers.facebook.com/docs/marketing-api/get-started/authentication) says "Every Marketing API call requires an access token as a parameter," and describes those two types.

| Token | Who grants it | Lifetime, per Meta | Best for |
|---|---|---|---|
| **Short-lived user token** | A person, through Facebook Login | About 1 to 2 hours | The OAuth handoff and testing |
| **Long-lived user token** | Exchanged from a short-lived one on your server | About 60 days | Platforms acting on customers' ad accounts |
| **System user token** | An admin in your business portfolio | Non-expiring, or 60 days if you opt in | Server jobs on your own business's assets |
| **Page access token** | Exchanged from a user token | Depends on the user token | Lead form reads and Page calls, not ad account calls |

Meta's [lead retrieval guide](https://developers.facebook.com/docs/marketing-api/guides/lead-ads/retrieving) accepts "a Page or User access token requested by a person who can advertise on the ad account." For campaigns, ad sets, ads, and insights, use the user or system user token. Our [Facebook Page access token guide](https://www.tryadeli.com/blog/facebook-page-access-token) covers Page tokens.

## Which permissions does the token need?

**A Meta Ads API token needs `ads_management` to change ads, or `ads_read` to report only.** The token carries whatever the person approved on the consent screen, so request the scopes in the Facebook Login `scope` parameter.

| Permission | What Meta says it allows |
|---|---|
| `ads_management` | Read and manage the ad account the app owns or one the owner grants access to |
| `ads_read` | Access the Ads Insights API to pull ad report information |
| `business_management` | Read and write with the Business Manager API |
| `pages_manage_ads` | Manage ads associated with a Page |
| `leads_retrieval` | Retrieve information captured by a lead ads form |

Source: Meta's [permissions reference](https://developers.facebook.com/docs/permissions). For ad accounts you don't own, Meta's [authorization guide](https://developers.facebook.com/docs/marketing-api/get-started/authorization) says you need **Advanced Access** to `ads_management` or `ads_read`, which requires Business Verification.

The token is also bounded by the person's role. A token from someone without a role on an ad account can't reach that account, whatever the scopes say.

## How to get a Meta Ads API access token for testing

**The Graph API Explorer generates a short-lived user token for your own ad accounts in about a minute.** Meta's authentication guide lists the steps:

1. Open the [Graph API Explorer](https://developers.facebook.com/tools/explorer/) and pick your app under **Meta App**.
2. Under **User or Page**, choose **User Token**.
3. Add `ads_read` or `ads_management` under **Permissions**.
4. Click **Generate Access Token** and approve the dialog.

Test the token by listing your ad accounts:

```bash
curl -G "https://graph.facebook.com/v26.0/me/adaccounts" \
  --data-urlencode "fields=name,account_status" \
  --data-urlencode "access_token=$USER_TOKEN"
```

## How to get a token from your customers in production

**Production tokens come from Facebook Login: your customer approves the scopes, and your server exchanges the code.** This is the flow for a platform that manages ads on its customers' accounts.

### Step 1: Send the customer to the login dialog

Redirect to Meta's OAuth dialog with your App ID, a redirect URI, and `scope=ads_management,business_management`. After the customer clicks **Allow**, Meta redirects to your URI with a `code`.

### Step 2: Exchange the code on your server

```bash
curl -G "https://graph.facebook.com/v26.0/oauth/access_token" \
  --data-urlencode "client_id=$APP_ID" \
  --data-urlencode "redirect_uri=$REDIRECT_URI" \
  --data-urlencode "client_secret=$APP_SECRET" \
  --data-urlencode "code=$CODE"
```

The response holds a short-lived user token.

### Step 3: Exchange it for a long-lived token

```bash
curl -G "https://graph.facebook.com/v26.0/oauth/access_token" \
  --data-urlencode "grant_type=fb_exchange_token" \
  --data-urlencode "client_id=$APP_ID" \
  --data-urlencode "client_secret=$APP_SECRET" \
  --data-urlencode "fb_exchange_token=$SHORT_LIVED_TOKEN"
```

Meta's [long-lived token guide](https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived) says to make this call from your server, and that you can't use an expired token to request a long-lived one. Store the result against the customer, never in a browser or mobile app.

Rashed Talukder made the same point about app credentials on the [Meta for Developers blog](https://developers.facebook.com/blog/post/2022/12/05/auth-tokens/) in December 2022:

> "It's important to remember that you should never embed an App Access Token in a mobile or desktop application."

The App Secret used in Steps 2 and 3 falls under the same rule. Keep it, and the tokens it mints, on the server.

## When should you use a system user token instead?

**Use a system user access token when your own server acts on assets your own business portfolio owns or has been shared.** Meta's guide says system user tokens are "useful for server-to-server interactions where there is no user present to authenticate." They don't depend on an employee's login, so a password change doesn't break them.

A system user can only reach assets assigned to it in your business portfolio, so it isn't a way to reach a customer's ad account without their consent. The setup, limits, and expiry options are in our [Meta system user access token guide](https://www.tryadeli.com/blog/meta-system-user-access-token).

## How do I debug a Meta Ads API access token?

**Call `debug_token` to see whether a token is valid, when it expires, and which scopes it holds.** You can also paste it into Meta's [Access Token Debugger](https://developers.facebook.com/tools/debug/accesstoken/).

```bash
curl -G "https://graph.facebook.com/debug_token" \
  --data-urlencode "input_token=$USER_TOKEN" \
  --data-urlencode "access_token=$APP_ID|$APP_SECRET"
```

The response includes `is_valid`, `expires_at`, `data_access_expires_at`, and `scopes`. Meta warns in its [access token guide](https://developers.facebook.com/docs/facebook-login/guides/access-tokens) that lifetimes "may change without warning or expire early," so read `expires_at` instead of hardcoding 60 days.

These are the errors you'll see most, from Meta's [Graph API error handling](https://developers.facebook.com/docs/graph-api/guides/error-handling) page:

| Error | Meaning | Fix |
|---|---|---|
| **190, subcode 463** | Token expired | Send the person through Facebook Login again |
| **190, subcode 460** | Password changed | The person logs in to your app again |
| **190, subcode 458** | App authorization removed | Ask the customer to reconnect |
| **10 or 200–299** | Permission missing or removed | Request the scope again |
| **17 or 80004** | Throttled | Back off; see our [Meta Marketing API rate limit guide](https://www.tryadeli.com/blog/meta-marketing-api-rate-limit) |

**Treat 190 as a reconnect.** Retrying a dead token only adds to your call count.

## How does Adeli handle Meta Ads tokens?

**Adeli runs the Facebook Login step for your customers and calls the Marketing API with their connection, so your product never stores a Meta token.** Your server holds one Adeli API key.

- **Connect.** Adeli uses Facebook Login for Business. Approved opt-in Ads grants add `ads_management`, `business_management`, `pages_manage_ads`, and `leads_retrieval` to the Facebook connection, per the [connect docs](https://www.tryadeli.com/docs/api/connect).
- **No `ads_read`.** The [Ads docs](https://www.tryadeli.com/docs/api/ads) say Adeli uses `ads_management` for reads and management and doesn't request `ads_read`.
- **Older connections.** A Facebook connection made before the Ads grants is sent through an explicit authorization flow before any Marketing API request.
- **Clear errors.** A healthy connection missing a required permission returns `403 permission_required`, and an expired credential is reported as a separate error.

Meta's access tier and the customer's ad-account role still apply. [AI marketing platforms](https://www.tryadeli.com/use-cases/ai-marketing-platforms) use the Ads endpoints with the same key as the rest of Adeli's [Facebook API](https://www.tryadeli.com/product/facebook), and Adeli bills per user profile; see [pricing](https://www.tryadeli.com/pricing).

## Frequently asked questions

### Is there a Meta Ads API key?

No. The Meta Marketing API has no API key. Your app has an App ID and an App Secret, which stay on your server, and each call carries an access token for a person or a system user with access to the ad account.

### How long does a Meta Ads API access token last?

Meta says a short-lived user token typically lasts one to two hours and a long-lived user token about 60 days. A system user token is non-expiring by default, or lasts 60 days if you generate it with set_token_expires_in_60_days. Any of them can be invalidated early.

### Can I use the Graph API Explorer token in production?

No. The Graph API Explorer gives you a short-lived token for your own testing. Production apps get user tokens from each customer through Facebook Login, or system user tokens for their own business assets.

### Why does my Meta Ads API token return error 190?

Error 190 means the access token is expired or invalid. The subcode says why, such as 463 for expired or 460 for a changed password. Send the person back through Facebook Login rather than retrying the call.

## Related Adeli pages

- [Facebook API for Developers](https://www.tryadeli.com/product/facebook.md): Publish, schedule, and read analytics for Facebook Pages through one API. Adeli owns the Facebook developer app, token refresh, and Meta review. Free to start.
- [Social Media and Ads API for AI Marketing Platforms](https://www.tryadeli.com/use-cases/ai-marketing-platforms.md): Run posting, analytics, inbox, and Meta ads for your customers' accounts through one API, without months of platform reviews.
- [Adeli Pricing — priced per profile](https://www.tryadeli.com/pricing.md): Your first 2 profiles are free, with up to 2 social accounts each. Then $6 each for profiles 3–10, $4 for 11–50, $3 for 51–100, $2 for 101–500, and $1.50 from profile 501. Every platform is included in each profile.
- [All posts on the Adeli blog](https://www.tryadeli.com/blog.md)

## About the author

Mika Reyes is the CEO behind Adeli and a tech and AI content creator. She was previously co-founder and CEO of Parallax, which was acquired by Phantom, and a product lead at LinkedIn. She is a Forbes 30 Under 30 honoree.
