What is the Facebook Graph API?
The Graph API is the main way apps get data into and out of Facebook. Meta’s overview describes it as nodes, edges and fields, and every request goes to the host graph.facebook.com. The Pages API, the Instagram API and much of the Marketing API are sets of Graph API endpoints with their own permissions, so learning the Graph API once covers most Meta integrations.
“Facebook API”, “Facebook Graph API”, “Meta Graph API” and “graph api facebook” all refer to the same thing. The company changed its name to Meta; the API and the host did not.
Nodes, edges and fields in one example
- Node: a single object with an ID, such as a Page, a post, a photo or a comment.
GET /PAGE_IDreads a node. - Edge: a collection hanging off a node, such as a Page’s posts.
GET /PAGE_ID/postsreads an edge;POST /PAGE_ID/feedwrites to one. - Field: a property you ask for explicitly with
fields=. By default you only get a few (usuallyidand a name).
This single request reads a Page node, two of its fields, and the last three items on its posts edge with their own fields (field expansion):
curl -G "https://graph.facebook.com/v26.0/PAGE_ID" \
-d "fields=name,followers_count,posts.limit(3){message,created_time}" \
-d "access_token=PAGE_ACCESS_TOKEN"{
"name": "Acme Coffee",
"followers_count": 12840,
"posts": {
"data": [
{ "message": "New roast is in", "created_time": "2026-09-27T15:02:11+0000", "id": "PAGE_ID_POST_ID" }
]
},
"id": "PAGE_ID"
}Three ideas carry you through the rest of the API: ask for the fields you need, follow edges to get related objects, and write by sending POST to an edge.
Graph API Explorer: test a call in two minutes
The Graph API Explorer (people also search for it as “Facebook Graph Explorer” or “Meta Graph API Explorer”) is Meta’s browser tool for building and running Graph API requests. It works for any app where you are an admin, developer or tester. Per Meta’s Explorer guide:
- Create an app in the Meta for Developers dashboard if you do not have one. The Explorer only lists apps where you have a role.
- Pick the app in the Meta App dropdown at the top.
- Choose the token type in the User or Page dropdown. Start with a user token.
- Add permissions in the Permissions dropdown. For Page publishing add
pages_show_list,pages_read_engagementandpages_manage_posts. - Generate the access token and approve the Facebook dialog, selecting the Pages you want the app to see. The token appears at the top right.
- Run a query, for example
me/accounts?fields=id,name,access_token. The response lists your Pages with a Page token each. Switch the User or Page dropdown to a Page to use its token directly. - Pick the version and method (GET, POST, DELETE) from the dropdowns next to the query field.
- Click Get Code to turn the working query into sample code.
The token the Explorer gives you is short-lived. It is perfect for testing and useless for a cron job. The next two sections fix that.
Access token types compared
Every Graph API call carries an access token. Meta’s access token guide lists these types:
| Token | Lifetime | How you get it | Use it for |
|---|---|---|---|
| User (short-lived) | About 1 to 2 hours | Facebook Login or the Graph API Explorer | Acting for a person in real time |
| User (long-lived) | About 60 days | Server-side exchange with fb_exchange_token | Getting Page tokens, background jobs for a user |
| Page | From a long-lived user token: no expiration date | GET /me/accounts with a user token | Reading and publishing Page content |
| App | Not stated in the token guide | Server call with app ID and app secret | Reading and changing app settings |
| System user | Long-lived ones do not expire based on time | Created for a business, not tied to a person | Automated actions on a business’s Pages or ads, no person in the loop |
| Client | Not stated in the token guide | App dashboard | Identifying your app in native or desktop apps |
Meta’s own warning: do not depend on these lifetimes staying the same; tokens can change or expire early. Sources: access tokens, long-lived tokens. Read 28 September 2026.
A Page token is unique to each combination of Page, admin and app. Keep app secrets and long-lived tokens on your server, never in a browser or mobile app.
Get a Page access token that never expires
This is the question behind half of all Graph API forum threads. Meta’s long-lived token guide gives the recipe: a Page token obtained with a long-lived user token has no expiration date.
- Get a short-lived user token with
pages_show_list,pages_read_engagementandpages_manage_posts(from the Explorer or your Facebook Login flow). - On your server, exchange it for a long-lived user token (about 60 days).
- Call
/me/accountswith the long-lived token. Each Page in the response has its ownaccess_token. - Store that Page token encrypted on your server.
# 1. Short-lived user token (from the Explorer or Facebook Login)
# -> long-lived user token (about 60 days)
curl -G "https://graph.facebook.com/v26.0/oauth/access_token" \
-d "grant_type=fb_exchange_token" \
-d "client_id=APP_ID" \
-d "client_secret=APP_SECRET" \
-d "fb_exchange_token=SHORT_LIVED_USER_TOKEN"
# 2. Long-lived user token -> Page tokens with no expiration date
curl -G "https://graph.facebook.com/v26.0/me/accounts" \
-d "fields=id,name,access_token" \
-d "access_token=LONG_LIVED_USER_TOKEN"“No expiration date” is not “valid forever”. Meta says these tokens can still be invalidated under certain conditions, and the error codes show the usual ones: the person changed their password or removed your app. Build a reconnect path for when you get error 190.
Permissions and App Review checklist
To publish on a Page, the permissions reference and the Pages API posts guide require:
pages_manage_posts: create, edit and delete Page posts. It depends on the next two.pages_read_engagement: read content the Page posted.pages_show_list: list the Pages a person manages.- For managing comments and reading user content on the Page, the posts guide also lists
pages_manage_engagementandpages_read_user_engagement. - The person behind the token must be able to perform the CREATE_CONTENT task on the Page (the posts guide lists CREATE_CONTENT, MANAGE and MODERATE for the full feature set).
Then there is access level, which is where most projects stall (access levels):
- Standard Access is granted automatically, but the permission only works for people with a role on your app. Fine for your own Pages and for testing.
- Advanced Access lets any Facebook user grant the permission. Each permission has to pass App Review, and since February 1, 2023 Advanced Access also requires Business Verification.
- Apps with Advanced Access must complete an annual Data Use Checkup.
In practice: if you only post to Pages you manage, Standard Access and a role on the app are enough. If customers connect their own Pages to your product, plan for App Review (screencasts of each permission in use) and business verification before launch.
Publish to a Facebook Page with curl
All examples use a Page access token and v26.0. Replace PAGE_ID with the numeric Page ID from /me/accounts.
Text and link posts
Send message, link or both to the Page’s feed edge. Facebook renders a preview card for the link.
curl -X POST "https://graph.facebook.com/v26.0/PAGE_ID/feed" \
-d "message=Our fall menu is live" \
-d "link=https://example.com/fall-menu" \
-d "access_token=PAGE_ACCESS_TOKEN"
# Response
{ "id": "PAGE_ID_POST_ID" }Photo posts
Use the photos edge with either url (a public image URL) or source (the file as multipart form data), plus an optional caption (Page photos reference).
curl -X POST "https://graph.facebook.com/v26.0/PAGE_ID/photos" \
-d "url=https://example.com/images/latte.jpg" \
-d "caption=Pumpkin spice is back" \
-d "access_token=PAGE_ACCESS_TOKEN"
# Or upload the file itself with the source field
curl -X POST "https://graph.facebook.com/v26.0/PAGE_ID/photos" \
-F "[email protected]" \
-F "caption=Pumpkin spice is back" \
-F "access_token=PAGE_ACCESS_TOKEN"Video posts
The Page videos edge accepts the file as source or a public file_url, with title and description. Video requests go to graph-video.facebook.com. For large files Meta recommends the Resumable Upload API: start a session with POST /APP_ID/uploads, upload the bytes, then publish with the returned handle. Reels have their own flow on the video_reels edge.
curl -X POST "https://graph-video.facebook.com/v26.0/PAGE_ID/videos" \
-F "file_url=https://example.com/videos/behind-the-bar.mp4" \
-F "title=Behind the bar" \
-F "description=How we pull a shot in 25 seconds" \
-F "access_token=PAGE_ACCESS_TOKEN"Scheduled posts
Set published=false and scheduled_publish_time to a Unix timestamp. For feed posts the time must be between 10 minutes and 30 days from the request. The Page videos reference allows 10 minutes to 6 months for video. Photos take the same two fields.
# Unix timestamp (here Oct 5, 2026 9:00 New York), 10 min to 30 days ahead
curl -X POST "https://graph.facebook.com/v26.0/PAGE_ID/feed" \
-d "message=Doors open at 7am tomorrow" \
-d "published=false" \
-d "scheduled_publish_time=1791205200" \
-d "access_token=PAGE_ACCESS_TOKEN"One detail from the posts guide that bites later: an app can only update a Page post that was made with that same app.
Rate limits, briefly
Meta’s rate limiting page describes two families that matter for Page tools:
- Platform rate limits (app and user tokens): calls within one hour = 200 × number of users of your app. Usage comes back in the
X-App-Usageheader as percentages of call count, CPU time and total time. - Business Use Case (BUC) limits (Page and system user tokens): for the Pages API, calls within 24 hours = 4,800 × number of engaged users of the Page. Usage comes back in
X-Business-Use-Case-Usage, which also includesestimated_time_to_regain_access.
Throttling errors use codes 4 (app limit), 17 (user limit), 32 (Page or user limit), 613 (custom limit) and 80001 (Pages BUC limit). When you see one, stop calling; hammering extends the block. Read the headers on every response and slow down before you hit 100%.
Common Graph API errors and fixes
| Code | Meaning | What to do |
|---|---|---|
| 190 | Access token invalid. Subcode 463 = expired, 460 = password changed, 458 = app removed | Get a new token; ask the person to reconnect |
| 10, 200-299 | Permission missing or denied | Request the permission, check access level and the person’s Page task |
| 4, 17, 32, 613, 80001 | Rate limited | Back off and read the usage headers |
| 368 | Temporarily blocked for a policy violation | Wait, then review the content |
| 506 | Duplicate post | Change the content before retrying |
| 1609005 | Error posting the link | Check the URL is valid and reachable |
| 1, 2 | Unknown or temporary API problem | Retry after a short wait |
Source: Graph API error handling. Read 28 September 2026.
Errors come back as JSON with a code, an optional error_subcode and an fbtrace_id to quote if you ask Meta for help:
{
"error": {
"message": "Error validating access token: Session has expired",
"type": "OAuthException",
"code": 190,
"error_subcode": 463,
"fbtrace_id": "EJplcsCHuLu"
}
}What the Graph API cannot do
- Post to a personal profile. Meta deprecated
publish_actions, the permission that let apps post as the logged-in user: about 60,000 apps lost it on August 1, 2018 and the last extensions ended on February 1, 2020 (Meta). The user feed endpoint does not support creating posts. The alternative is the Share dialog, where the person posts manually. - Post to Groups. The Groups API, with
publish_to_groupsandgroups_access_member_info, was deprecated in v19.0 (January 23, 2024) and removed on April 22, 2024 (v19.0 changelog). - Edit posts another app made. Updates only work on posts your app created.
- Schedule a feed post more than 30 days out through Meta’s own scheduler. Longer horizons need your own queue.
Any tool that promises automatic posting to profiles or Groups in 2026 is either not using the official API or not telling you the whole story.
Versioning: v26.0 and the two-year rule
The latest version is v26.0, released on July 29, 2026 (changelog). Some pages still say v25.0: that shipped on February 18, 2026 and is available until July 29, 2028. Earlier ones still running: v24.0 until February 18, 2028, v23.0 until October 8, 2027 and v22.0 until May 20, 2027.
The versioning policy: each version stays active for at least two years after release. A request without a version uses the default set in your app dashboard (Settings, Advanced). When a version expires, calls to it are served by the next oldest version that still works, which can change responses without warning. Pin the version in every URL and put the expiry date in your calendar.
Is the Facebook Graph API free?
Meta publishes no price for Graph API calls, and creating an app is free. The real costs are the limits above, the App Review and Business Verification work if other people will connect their Pages, and maintenance: a version upgrade at least every two years and a token refresh flow. Meta’s paid products, such as ads and WhatsApp Business messaging, are billed on their own terms.
The shortcut: post to Facebook Pages with one Upload-Post call
If your goal is publishing, the Graph API is mostly plumbing: an app, a review, token exchanges, a reconnect flow, a video upload protocol, version bumps. Upload-Post is a social media posting API that already did that work for Facebook and 21 other platforms through their official APIs. You connect a Page once in the dashboard or through a white-label connect link, then:
# List the Pages connected to a profile (get the id once)
curl "https://api.upload-post.com/api/uploadposts/facebook/pages?profile=acme" \
-H "Authorization: Apikey YOUR_KEY"
# Publish one video to a Facebook Page and Instagram, scheduled
curl -X POST https://api.upload-post.com/api/upload \
-H "Authorization: Apikey YOUR_KEY" \
-F "user=acme" \
-F "[email protected]" \
-F "title=Behind the bar" \
-F "platform[]=facebook" \
-F "platform[]=instagram" \
-F "facebook_page_id=109876543210987" \
-F "facebook_media_type=REELS" \
-F "scheduled_date=2026-10-05T09:00:00" \
-F "timezone=America/New_York"- Same content, several networks. Add
platform[]=instagram,tiktok,youtubeorlinkedinto the same request. See posting to multiple social networks at once. - Facebook formats. Videos as Reels (default), normal Page videos or Stories with
facebook_media_type; photos and albums through/api/upload_photos; text and link posts through/api/upload_textwithfacebook_link_url. - Scheduling beyond 30 days.
scheduled_datewith atimezoneworks up to 365 days ahead, or use a queue withadd_to_queue=true. - Page analytics.
GET /api/analytics/PROFILE?platforms=facebook&page_id=...returns impressions and reach for a window of 1 to 365 days. - Tokens handled. No Meta app, App Review or token exchange on your side.
Be clear about scope. Upload-Post covers publishing, scheduling, first comments and analytics for Pages you connect. It is not a general Graph API proxy: to read arbitrary Graph data, run ads through the Marketing API or add Facebook Login to your app, you still need your own Meta app. And the same Meta rules apply: Pages only, no profiles, no Groups.
The Free plan is free forever with no card: 10 uploads a month and 2 profiles, Facebook included. Paid plans with unlimited uploads start at $24 a month ($16 a month billed annually). Full parameters are in the API docs, and the Facebook API page lists every Facebook option. Building for more networks? Read the Instagram API guide, the Threads API guide and the social media API overview.
Frequently asked questions
Is the Facebook Graph API free?
Yes, in the sense that Meta does not publish a price for Graph API calls: creating an app and calling the Pages endpoints costs nothing. What you pay with is time and limits. Calls are rate limited, and to use Page permissions with people who have no role on your app you need Advanced Access, which means App Review and Business Verification. Paid Meta products such as ads and WhatsApp Business conversations are billed separately.
What is the Graph API Explorer?
The Graph API Explorer is Meta’s web tool at developers.facebook.com/tools/explorer for building and running Graph API requests against apps where you are an admin, developer or tester. You pick an app, choose a user or Page token, tick permissions, generate the token and run a query. The Get Code button turns a working query into sample code. It is the fastest way to test a call before you write any code.
How do I get a Facebook Page access token that does not expire?
Get a short-lived user token with pages_show_list, pages_read_engagement and pages_manage_posts (the Graph API Explorer works), exchange it for a long-lived user token with GET /oauth/access_token and grant_type=fb_exchange_token, then call GET /me/accounts with that long-lived token. The Page tokens it returns have no expiration date. Meta notes they can still be invalidated under certain conditions, so handle error 190 anyway.
Can I post to my personal Facebook profile with the Graph API?
No. Meta deprecated the publish_actions permission, which let apps post as the logged-in user, in 2018: most apps lost it on August 1, 2018 and the last extensions ended on February 1, 2020. The user feed endpoint does not support creating posts. The only supported option for personal profiles is the Share dialog, where the person posts themselves. Every legitimate scheduling tool, Upload-Post included, publishes to Pages only.
Can I post to Facebook Groups with the API?
No. Meta deprecated the Groups API with Graph API v19.0 in January 2024 and removed it, together with the publish_to_groups and groups_access_member_info permissions, on April 22, 2024. No third-party app can publish to a Facebook Group through the API any more.
What is the current Facebook Graph API version?
v26.0, released on July 29, 2026. The previous version, v25.0 (February 18, 2026), stays available until July 29, 2028. Meta guarantees each version for at least two years after release, and calls to an expired version are served by the next oldest version that is still available. Always put the version in the URL, for example graph.facebook.com/v26.0/.
How do I schedule a Facebook Page post with the Graph API?
Send POST /PAGE_ID/feed with published=false and scheduled_publish_time set to a Unix timestamp between 10 minutes and 30 days in the future, using a Page access token. Photos and videos accept the same two fields on /photos and /videos; the Page videos reference allows up to six months ahead for video.
What is the difference between the Meta Graph API and the Facebook Graph API?
They are the same API. The company is now called Meta, so newer docs say Meta Graph API, but the host is still graph.facebook.com and the version numbers are shared. The Instagram API and parts of the Marketing API are built on the same Graph API, with their own endpoints and permissions.
Why does my Graph API call return error 190?
Code 190 means the access token is no longer valid. The subcode tells you why: 463 means it expired, 460 means the person changed their password, and 458 means they removed your app. The fix in every case is a new token, which for a Page means repeating the long-lived exchange and calling /me/accounts again.
Can Upload-Post replace the Graph API for my project?
If you need to publish, schedule or measure posts on Facebook Pages (and the same content on Instagram, TikTok, YouTube and more), yes: one Upload-Post request does it and Upload-Post handles the Meta app, review and tokens. If you need to read arbitrary Graph data, manage ads or build Facebook Login, you still need your own Meta app and the Graph API.