Install
openclaw skills install facebook-page-apiFacebook Page API integration with managed OAuth. Manage pages, posts, comments, insights, photos, videos, and product catalogs. Use this skill when users wa...
openclaw skills install facebook-page-apiAccess the Facebook Graph API with managed OAuth authentication. Manage pages, publish and read posts, view page insights, manage comments, and access photos and videos.
# List your Facebook Pages
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/facebook-page/v25.0/me/accounts?fields=id,name,category,fan_count,followers_count')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/facebook-page/{native-api-path}
Maton proxies requests to graph.facebook.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Facebook Page OAuth connections at https://api.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=facebook-page&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'facebook-page'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "facebook-page",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Facebook Page connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/facebook-page/v25.0/me/accounts?fields=id,name')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
Most page-specific endpoints (feed, insights, comments, etc.) require a Page Access Token. The gateway injects a User Access Token, but the Facebook API requires a Page Access Token for page operations. Endpoints that only need a User Access Token (like GET /me/accounts and GET /{page_id}) work without a Page Access Token.
Retrieve the page access token from /me/accounts and pass it as a query parameter access_token in subsequent requests:
python <<'EOF'
import urllib.request, os, json
# Step 1: Get page token
req = urllib.request.Request('https://api.maton.ai/facebook-page/v25.0/me/accounts?fields=id,name,access_token')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
pages = json.load(urllib.request.urlopen(req))
page_id = pages['data'][0]['id']
page_token = pages['data'][0]['access_token']
# Step 2: Use page token for page-specific endpoints
req = urllib.request.Request(f'https://api.maton.ai/facebook-page/v25.0/{page_id}/feed?fields=id,message,created_time&limit=10&access_token={page_token}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Returns all Facebook Pages managed by the authenticated user. Works with the gateway-injected User Access Token (no access_token query parameter needed).
GET /facebook-page/v25.0/me/accounts?fields=id,name,category,fan_count,followers_count
Response:
{
"data": [
{
"id": "953430301193656",
"name": "Maton",
"category": "Software",
"fan_count": 0,
"followers_count": 0
}
],
"paging": {
"cursors": {
"before": "...",
"after": "..."
}
}
}
Available Fields: id, name, access_token, category, category_list, tasks
Returns details for a specific page. Works with User Access Token.
GET /facebook-page/v25.0/{page_id}?fields=id,name,about,category,fan_count,followers_count,website,phone,emails,link,verification_status
Response:
{
"id": "953430301193656",
"name": "Maton",
"category": "Software",
"fan_count": 0,
"followers_count": 0,
"link": "https://www.facebook.com/953430301193656",
"verification_status": "not_verified"
}
Available Fields: id, name, about, description, category, category_list, fan_count, followers_count, talking_about_count, cover, picture, website, phone, emails, location, hours, link, verification_status, is_published
All post endpoints require a Page Access Token passed as the access_token query parameter.
GET /facebook-page/v25.0/{page_id}/feed?fields=id,message,created_time,type&limit=10&access_token={page_access_token}
Response:
{
"data": [
{
"id": "953430301193656_122095067559277233",
"message": "Hello world!",
"created_time": "2026-02-16T06:47:45+0000"
}
],
"paging": {
"cursors": {
"before": "...",
"after": "..."
}
}
}
GET /facebook-page/v25.0/{page_id}/published_posts?fields=id,message,created_time&limit=10&access_token={page_access_token}
POST /facebook-page/v25.0/{page_id}/feed?access_token={page_access_token}
Content-Type: application/json
{
"message": "Hello from my page!"
}
Response:
{
"id": "953430301193656_122110982931277233"
}
Available Fields:
message (string) - Post text contentlink (string) - URL to attachpublished (boolean) - Set false to create an unpublished/draft postscheduled_publish_time (int) - UNIX timestamp for scheduling future postsplace (string) - Location ID to tagtags (string) - Comma-separated user IDs to tag (requires place)POST /facebook-page/v25.0/{page_id}/feed?access_token={page_access_token}
Content-Type: application/json
{
"message": "Check out this article!",
"link": "https://example.com/article"
}
POST /facebook-page/v25.0/{post_id}?access_token={page_access_token}
Content-Type: application/json
{
"message": "Updated post content"
}
Response:
{
"success": true
}
DELETE /facebook-page/v25.0/{post_id}?access_token={page_access_token}
Response:
{
"success": true
}
All comment endpoints require a Page Access Token.
GET /facebook-page/v25.0/{post_id}/comments?fields=id,message,from,created_time&access_token={page_access_token}
Response:
{
"data": [
{
"id": "122110982931277233_2054970148765241",
"message": "Great post!",
"from": {
"name": "User Name",
"id": "123456789"
},
"created_time": "2026-04-13T22:00:00+0000"
}
]
}
POST /facebook-page/v25.0/{post_id}/comments?access_token={page_access_token}
Content-Type: application/json
{
"message": "Thanks for your feedback!"
}
Response:
{
"id": "122110982931277233_2054970148765241"
}
DELETE /facebook-page/v25.0/{comment_id}?access_token={page_access_token}
Page Insights endpoints require a Page Access Token.
GET /facebook-page/v25.0/{page_id}/insights?metric=page_views_total,page_posts_impressions,page_video_views&period=day&access_token={page_access_token}
Available Metrics:
| Metric | Description |
|---|---|
page_views_total | Total page views |
page_posts_impressions | Total impressions of page posts |
page_video_views | Total video views on the page |
Deprecated Metrics:
| Deprecated | Use Instead |
|---|---|
page_impressions | page_views_total |
page_engaged_users | page_posts_impressions |
page_fans | fan_count field on page |
Period Values: day, week, days_28
GET /facebook-page/v25.0/{page_id}/insights?metric=page_views_total&period=day&since=2026-01-01&until=2026-01-31&access_token={page_access_token}
Response:
{
"data": [
{
"name": "page_views_total",
"period": "day",
"values": [
{
"value": 150,
"end_time": "2026-01-02T08:00:00+0000"
}
],
"title": "Total views",
"id": "{page_id}/insights/page_views_total/day"
}
],
"paging": {
"previous": "...",
"next": "..."
}
}
GET /facebook-page/v25.0/{page_id}/photos?fields=id,name,created_time,images&limit=10&access_token={page_access_token}
Response:
{
"data": [
{
"id": "122095067559277233",
"created_time": "2026-02-16T06:48:02+0000",
"images": [
{
"height": 512,
"source": "https://scontent.xx.fbcdn.net/...",
"width": 512
}
]
}
],
"paging": {
"cursors": {
"before": "...",
"after": "..."
}
}
}
POST /facebook-page/v25.0/{page_id}/photos?access_token={page_access_token}
Content-Type: application/json
{
"url": "https://example.com/photo.jpg",
"caption": "My photo caption"
}
GET /facebook-page/v25.0/{page_id}/videos?fields=id,title,description,created_time&limit=10&access_token={page_access_token}
GET /facebook-page/v25.0/{page_id}/product_catalogs?access_token={page_access_token}
Response:
{
"data": [
{
"id": "catalog_id",
"name": "My Product Catalog"
}
]
}
GET /facebook-page/v25.0/{catalog_id}/products?fields=id,name,price,image_url&access_token={page_access_token}
Response:
{
"data": [
{
"id": "product_id",
"name": "Example Product",
"price": "$19.99",
"image_url": "https://example.com/product.jpg"
}
]
}
The Facebook Graph API uses cursor-based pagination. Responses include paging.cursors.before and paging.cursors.after values.
GET /facebook-page/v25.0/{page_id}/feed?fields=id,message&limit=10&after={after_cursor}&access_token={page_access_token}
Response includes pagination info:
{
"data": [...],
"paging": {
"cursors": {
"before": "...",
"after": "..."
},
"next": "https://graph.facebook.com/...",
"previous": "https://graph.facebook.com/..."
}
}
Use the after cursor value for the next page, and before for the previous page. The limit parameter controls the number of results per page (max 100 for feed).
// Step 1: Get page token
const accountsRes = await fetch(
'https://api.maton.ai/facebook-page/v25.0/me/accounts?fields=id,name,access_token',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const accounts = await accountsRes.json();
const pageId = accounts.data[0].id;
const pageToken = accounts.data[0].access_token;
// Step 2: Get page feed
const feedRes = await fetch(
`https://api.maton.ai/facebook-page/v25.0/${pageId}/feed?fields=id,message,created_time&limit=10&access_token=${pageToken}`,
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const feed = await feedRes.json();
import os
import requests
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Step 1: Get page token
accounts = requests.get(
'https://api.maton.ai/facebook-page/v25.0/me/accounts',
headers=headers,
params={'fields': 'id,name,access_token'}
).json()
page_id = accounts['data'][0]['id']
page_token = accounts['data'][0]['access_token']
# Step 2: Get page feed
feed = requests.get(
f'https://api.maton.ai/facebook-page/v25.0/{page_id}/feed',
headers=headers,
params={
'fields': 'id,message,created_time',
'limit': 10,
'access_token': page_token
}
).json()
access_token query parameterGET /me/accounts and GET /{page_id} endpoints work with the gateway-injected User Access Token directly{page_id}_{post_id}curl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Missing Facebook Page connection |
| 401 | Invalid or missing Maton API key |
| 190 | Invalid OAuth Access Token (Facebook error code) |
| 200 | Permissions error - missing required scope (Facebook error code) |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Facebook Graph API |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you get a "This method must be called with a Page Access Token" error, you need to include the page's access token as a query parameter. See the Page Access Token section above.
facebook-page. For example:https://api.maton.ai/facebook-page/v25.0/me/accountshttps://api.maton.ai/v25.0/me/accounts