All three platforms use OAuth 2.0 with localhost callback on port OAUTH_CALLBACK_PORT (default 3000). Run adskills init and pick the platform — the wizard opens the browser, captures the auth code, and stores the long-lived token encrypted.
- Create a Meta for Developers app at https://developers.facebook.com/apps/
- Enable the Marketing API product
- Add
http://localhost:3000/oauth/meta/callbackas an OAuth redirect URI - Copy App ID + App Secret into
.envMETA_APP_ID=... META_APP_SECRET=... META_REDIRECT_URI=http://localhost:3000/oauth/meta/callback adskills init→ Meta → complete the flow- The token is exchanged for a long-lived token (~60 days). Refresh by re-running
adskills initbefore expiry.
ads_management,ads_read— create/read campaigns, ads, creativesbusiness_management— access Business accounts and ad accountspages_read_engagement,pages_manage_ads— run ads on behalf of Pages
{
"acme": {
"meta": {
"adAccountId": "act_1234567890",
"businessId": "",
"tokenRef": "meta.acme"
}
}
}- Create a Google Cloud project and enable the Google Ads API
- Configure OAuth consent screen (External, Testing is fine for single-user use)
- Create an OAuth 2.0 Client ID (Web application) with redirect URI
http://localhost:3000/oauth/google/callback - Apply for a Developer Token at https://ads.google.com/aw/apicenter (Basic Access sufficient for reads and first-party customer match)
- Fill
.envGOOGLE_CLIENT_ID=... GOOGLE_CLIENT_SECRET=... GOOGLE_DEVELOPER_TOKEN=... GOOGLE_REDIRECT_URI=http://localhost:3000/oauth/google/callback adskills init→ Google Ads → complete the flow (refresh token is captured becauseaccess_type=offline+prompt=consent)
https://www.googleapis.com/auth/adwords— Ads APIhttps://www.googleapis.com/auth/drive.readonly— Drive folder source for bulk uploads (optional)
{
"acme": {
"google": {
"customerId": "123-456-7890",
"loginCustomerId": "111-111-1111",
"tokenRef": "google.acme"
}
}
}customerId— the ad account you want to manageloginCustomerId— set only when the token was authorized by an MCC (manager account). Dashes optional.
- Apply for LinkedIn Marketing Developer Platform at https://developer.linkedin.com/
- Create an app, request Advertising API + Community Management API products
- Add redirect URI
http://localhost:3000/oauth/linkedin/callback - Fill
.envLINKEDIN_CLIENT_ID=... LINKEDIN_CLIENT_SECRET=... LINKEDIN_REDIRECT_URI=http://localhost:3000/oauth/linkedin/callback adskills init→ LinkedIn Ads → complete the flow
r_ads,rw_ads— read + write campaigns, creatives, ad accountsr_ads_reporting— analytics endpointsr_organization_social,w_member_social— Page-level operations
{
"acme": {
"linkedin": {
"accountId": "urn:li:sponsoredAccount:123456789",
"tokenRef": "linkedin.acme"
}
}
}URN prefix is auto-added if you pass a raw numeric ID.
- Meta long-lived tokens expire after ~60 days — rerun
adskills init - Google refresh tokens do not expire (unless revoked) — the underlying
google-ads-apilib refreshes access tokens automatically - LinkedIn access tokens last 60 days; refresh tokens last 365 days. When close to expiry, rerun
adskills init.
Each accountRef in config/accounts.json points to a dedicated tokenRef. Running adskills init for a new account ref saves a separate token alongside the existing ones in the encrypted store.
adskills init # → accountRef: acme
adskills init # → accountRef: cliente2
adskills meta audit -a acme
adskills meta audit -a cliente2