Install
openclaw skills install platform-api-connectorConnect to social media and content platform APIs by navigating developer portals, creating apps, obtaining OAuth tokens, and storing credentials. Covers Facebook Graph API, Instagram Business API, YouTube Data API, Twitter/X API v2, and TikTok Content Posting API. Use when setting up API access for any social platform, refreshing expired OAuth tokens, or debugging authentication flows.
openclaw skills install platform-api-connectorNavigate developer portals and obtain API credentials for social/content platforms. Store credentials in Supabase (or any DB) for reuse.
Facebook and Instagram share the same auth system. One Facebook Page Token unlocks both.
developers.facebook.com/apps → Create App → Business typedevelopers.facebook.com/tools/explorer/):
pages_show_list, pages_read_engagement, pages_manage_posts, instagram_basic, instagram_content_publishGET /oauth/access_token?grant_type=fb_exchange_token&client_id={app_id}&client_secret={secret}&fb_exchange_token={short_token}GET /me/accounts → find page → copy access_tokenGET /{page_id}?fields=instagram_business_account{
"platform": "facebook",
"credentials": {
"app_id": "...",
"app_secret": "...",
"page_id": "...",
"page_access_token": "...",
"ig_user_id": "..."
}
}
Page Access Tokens from Graph API Explorer are short-lived unless you exchange the User Token for a long-lived one FIRST, then request Page tokens from the long-lived User Token. Page tokens derived from long-lived user tokens are permanent (no expiry).
console.cloud.google.com → APIs & Services → Credentialshttp://localhost:8422/callback (or your callback URL)from google_auth_oauthlib.flow import InstalledAppFlow
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json',
scopes=['https://www.googleapis.com/auth/youtube.upload',
'https://www.googleapis.com/auth/youtube.readonly']
)
creds = flow.run_local_server(port=8422)
# creds.token, creds.refresh_token, creds.expiry
{
"platform": "youtube",
"credentials": {
"client_id": "...",
"client_secret": "...",
"access_token": "...",
"refresh_token": "...",
"token_expiry": "..."
}
}
If the user previously authorized with limited scopes, the refresh token may not cover youtube.upload. Must re-authorize with prompt='consent' to get a new refresh token with full scopes.
developer.x.com/en/portal/dashboard{
"platform": "twitter",
"credentials": {
"api_key": "...",
"api_secret": "...",
"bearer_token": "...",
"access_token": "...",
"access_token_secret": "..."
}
}
Free tier caps at 100 posts/month (resets on billing date, not calendar month). No delete or analytics on free tier.
developers.tiktok.com → Create AppTikTok Content Posting API requires full app review with demo video. This takes days to weeks. Plan for Manual mode as interim solution. Login Kit can work in sandbox mode for development.
Use a single table with JSONB for flexibility:
CREATE TABLE platform_connections (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
platform TEXT NOT NULL,
account_name TEXT,
credentials JSONB NOT NULL,
scopes TEXT[],
status TEXT DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
JSONB accommodates different auth shapes per platform without schema changes.
async def get_valid_token(platform: str) -> dict:
conn = await get_connection(platform)
creds = conn['credentials']
if platform == 'youtube' and is_expired(creds.get('token_expiry')):
new_token = refresh_google_token(creds['refresh_token'], creds['client_id'], creds['client_secret'])
creds['access_token'] = new_token
await update_connection(conn['id'], creds)
# Facebook page tokens don't expire (if derived from long-lived user token)
# Twitter tokens don't expire
# TikTok tokens expire in 24h — refresh with refresh_token
return creds