ContentFlows/Documentation

Troubleshooting & token guides

Step-by-step instructions for connecting LinkedIn, Facebook, Instagram, and YouTube to ContentFlows. Each platform requires two values: an access token (what grants permission) and an ID (which account / page / channel to publish to). Both are pasted into your dashboard.

How credentials are stored

All four platforms' values are saved as a single encrypted JSON blob in AWS Secrets Manager at contentflows/tenants/YOUR_TENANT_ID/social-tokens. Secrets are never logged, never shown again after saving, and isolated to your account. ContentFlows never stores your social media password.


LinkedIn

ContentFlows uses the LinkedIn UGC Posts API to publish on your behalf. You need an access token with the w_member_social permission scope, plus the member URN of the account the posts should appear under.

Fields ContentFlows will ask you for

LINKEDIN_ACCESS_TOKEN
OAuth 2.0 access token (60-day lifespan). Starts with AQV… or similar.
LINKEDIN_AUTHOR_ID
Member URN — looks like urn:li:person:XXXXXXXXXX or urn:li:organization:NNNNNN for a Company Page.

Prerequisites

  • A LinkedIn account (personal profile) — posts will be published from this account
  • A free LinkedIn developer account — you create one automatically when you create an app

Step-by-step

1

Go to the LinkedIn Developer Portal

Open linkedin.com/developers/apps and log in. Click Create app.
2

Fill in the app details

  • App name: anything — e.g. “ContentFlows Publisher”
  • LinkedIn page: you must link a LinkedIn Company Page. If you don't have one, create a basic company page first (free).
  • App logo: upload any square image
Click Create app.
3

Request the 'Share on LinkedIn' product

On the app page, click the Products tab. Find Share on LinkedIn and click Request access. Usually approved instantly.
4

Add your redirect URI

Go to the Auth tab. Under OAuth 2.0 settings, add this redirect URL:
https://www.linkedin.com/developers/tools/oauth/redirect
Click Update.
5

Generate the access token

Go to linkedin.com/developers/tools/oauth/token-generator. Select your app, tick w_member_social (and r_liteprofile if available), click Request access token, click Allow. Copy the token — it won't be shown again. This is your LINKEDIN_ACCESS_TOKEN.
6

Find your Member URN

In the same token-generator tool, use the bundled API tester:
GET https://api.linkedin.com/v2/userinfo
The response contains sub — prefix it with urn:li:person: to form your URN. For example if sub = "ABC123xyz", your URN is urn:li:person:ABC123xyz. This is your LINKEDIN_AUTHOR_ID.
Tip: To post from a LinkedIn Company Page instead of your personal profile, use urn:li:organization:COMPANY_PAGE_NUMERIC_ID instead — the numeric ID is visible in the Page's admin URL.
7

Paste both values into ContentFlows

In your dashboard, go to Integrations → LinkedIn. Paste the access token into the Access token field and the URN into the Member URN field, then click Save.
Note: LinkedIn access tokens expire after 60 days. Repeat steps 5 and 7 every two months (the URN never changes). Set a calendar reminder.

Facebook

ContentFlows publishes to a Facebook Page (not a personal profile). You need a Page access token with pages_manage_posts permission, plus the numeric Page ID.

Fields ContentFlows will ask you for

FB_PAGE_ACCESS_TOKEN
Long-lived Page access token (60 days) from Meta for Developers.
FB_PAGE_ID
The numeric ID of the Facebook Page you manage (e.g. 123456789012345).

Prerequisites

  • A Facebook account that is an Admin of a Facebook Page
  • If you don't have a Facebook Page yet, create one at facebook.com/pages/create (free, takes 2 minutes)

Step-by-step

1

Open the Meta for Developers portal

Go to developers.facebook.com/apps and log in. Click Create App.
2

Select app type and fill in details

Choose Business as the app type. Fill in app name, contact email, click Create App.
3

Add the Facebook Login product

On the dashboard, find Facebook Login in the product list and click Set up. No extra configuration needed.
4

Get a user token from the Graph API Explorer

Open the Graph API Explorer:
  • In the top-right dropdown, select your app
  • Click Generate Access Token
  • In the permissions popup, check all of these:
    • pages_manage_postsrequired to publish posts (the most common missing scope)
    • pages_read_engagement
    • pages_show_list
    • business_management
    • instagram_basic — only if you plan to reuse this token for Instagram
    • instagram_content_publish — only if you plan to reuse this token for Instagram
  • Click Generate Access Token and authorize
This gives you a short-lived User access token (valid ~2 hours). Steps 5–6 convert it into a never-expiring Page access token.
5

Extend the user token to long-lived (60 days)

Paste the user token into the Access Token Debugger, click Debug, then click Extend Access Token at the bottom. You get a new user token valid for ~60 days. Use this extended token in the next step.
6

Derive the Page access token AND the Page ID

Back in the Graph API Explorer, paste the long-lived user token from step 5 into the Access Token field, then run:
GET /me/accountsSubmit
In the JSON response, find your Page. It has two important fields:
  • access_token → this is your FB_PAGE_ACCESS_TOKEN — because you derived it from a long-lived user token, this Page token never expires
  • id → this is your FB_PAGE_ID
Copy both values.
7

Paste both values into ContentFlows

In your dashboard, go to Integrations → Facebook. Paste the Page token into Page access token and the numeric page ID into Page ID, then click Save.
8

Verify the token has the right scopes (optional but recommended)

Paste your new Page token into the Access Token Debugger and check:
  • Type: PAGE (not USER — if it says USER, you copied the wrong token in step 6)
  • Expires: Never (if it shows a date, you skipped step 5 — the user token was still short-lived when you called /me/accounts)
  • Scopes: must include pages_manage_posts. If it's missing, you didn't check that box in step 4 — restart from step 4.
Tip: Common 403 cause: If your scheduled posts fail with {"error":{"message":"(#200) Permissions error"}}, the token is almost always missing pages_manage_posts. Verify with the debugger (step 8) and regenerate if needed.

Instagram

Instagram publishing uses the Facebook Graph API, so your Instagram account must be a Professional account (Business or Creator) linked to a Facebook Page. Personal Instagram accounts cannot publish via API.

Fields ContentFlows will ask you for

IG_ACCESS_TOKEN
Optional — leave blank and ContentFlows falls back to FB_PAGE_ACCESS_TOKEN. Fill in only if you have a dedicated Instagram token.
IG_BUSINESS_ACCOUNT_ID
The Instagram Business Account ID linked to your Facebook Page (e.g. 17841412345678901).

Prerequisites

  • An Instagram Business or Creator account (not a personal account)
  • That Instagram account linked to a Facebook Page you manage
  • A Meta developer app with instagram_content_publish permission

Convert to a Professional account (if needed)

1

Switch account type in the Instagram app

On your phone, go to your Instagram profile → tap the ☰ menu → SettingsAccountSwitch to Professional Account. Choose Business or Creator.
2

Link Instagram to your Facebook Page

Still in Instagram Settings, go to AccountLinked AccountsFacebook. Log in and select your Page.

Get the Instagram Business Account ID

3

Open the Graph API Explorer

Go to developers.facebook.com/tools/explorer. Select your app and generate a token with these permissions:
instagram_basic, instagram_content_publish, pages_read_engagement, pages_manage_posts
4

Find your Instagram Business Account ID

Run GET /me/accounts. Find your Page and copy its id. Then run:
GET /{page-id}?fields=instagram_business_account
(replace {page-id} with your Page ID). The response contains an instagram_business_account object — copy its id. This is your IG_BUSINESS_ACCOUNT_ID.
5

Paste the values into ContentFlows

In your dashboard, go to Integrations → Instagram. Paste the IG Business Account ID into Business Account ID. Leave the Access tokenfield blank to reuse the Facebook Page token you already configured — that's the simplest path and what most people do. Click Save.
Note: If you've already saved Facebook, Instagram's access token defaults to the FB Page token. You only need to provide IG_BUSINESS_ACCOUNT_ID.

YouTube

ContentFlows uses the YouTube Data API v3 to generate video metadata (titles, descriptions, tags) for your content calendar. You need an API key from Google Cloud Console and your channel's ID.

Fields ContentFlows will ask you for

YOUTUBE_API_KEY
Google Cloud API key with YouTube Data API v3 enabled. Starts with AIza…
YOUTUBE_CHANNEL_ID
Your YouTube channel ID (e.g. UCxxxxxxxxxxxxxxxxxxxxxx). Find it in YouTube Studio → Settings → Channel → Advanced settings.

Prerequisites

  • A Google account
  • A YouTube channel linked to that account
  • A free Google Cloud project (you create one during the first step)

Step-by-step

1

Create a Google Cloud project

Go to console.cloud.google.com/projectcreate, give your project any name (e.g. “ContentFlows”), and click Create.
2

Enable the YouTube Data API v3

With the new project selected, go to YouTube Data API v3 and click Enable.
3

Create an API key

Navigate to APIs & Services → Credentials. Click + Create credentials → API key. Copy the key — this is your YOUTUBE_API_KEY.
Tip: Click Restrict key and limit it to the YouTube Data API v3 for safety.
4

Find your YouTube Channel ID

Go to YouTube StudioSettings (bottom-left gear icon) → ChannelAdvanced settings. Your Channel ID is listed there — copy it. It starts with UC. This is your YOUTUBE_CHANNEL_ID.
5

Paste both values into ContentFlows

In your dashboard, go to Integrations → YouTube. Paste the API key into API key and the channel ID into Channel ID, then click Save.
Note: The API key is read-only — it generates metadata but does NOT upload videos. Uploading still requires OAuth, which isn't part of the onboarding flow today.


Sending domain (DKIM / SPF / DMARC)

By default newsletters go from noreply@contentflows.cc. Authenticating your own domain improves deliverability (fewer spam-folder landings) because the From address matches DKIM signatures and your visible brand.

Prerequisites

  • You own a domain (e.g. your-business.com).
  • You can create DNS records at your registrar (Cloudflare, Route53, GoDaddy, Namecheap, etc.).

Step-by-step

1

Start the flow

In your dashboard, open Brand → find the Sending domain card at the bottom → type your domain (e.g. your-business.com) → click Save & show DNS records.
2

Copy the 5 DNS records

The card now shows 5 records:
  • 3 × CNAME (DKIM tokens)
  • 1 × TXT at the root (SPF)
  • 1 × TXT at _dmarc.your-domain.com (DMARC)
Use the Copy button next to each row to grab them one at a time.
3

Paste into your DNS provider

Log in to your DNS host, create each record with the exact host/name and value as shown. For CNAMEs, don't add your domain as a suffix — the host shown is the full name (e.g. abc123._domainkey.your-domain.com).
Tip: Cloudflare users: disable the orange cloud (proxy) on the DKIM CNAMEs — SES needs the raw record.
4

Verify

Back in the dashboard, click I added the records — Verify. The card polls SES every 15 seconds for up to 10 minutes. Global DNS propagation is usually under 2 minutes but some providers need longer.
5

Done

Once verified, all newsletters from your tenant will use newsletter@your-domain.com as the From header, with DKIM signatures, SPF pass, and DMARC alignment.
Note: You can remove the domain anytime from the same card — emails then fall back to the shared noreply@contentflows.cc sender.

Importing subscribers

The Newsletter tab's + Importbutton opens a modal with three tabs:

CSV upload

Upload a .csv file. Header row is auto-detected (any column whose name contains email is treated as the email column; any column with name or first is treated as the name). Invalid email addresses are rejected; duplicates are skipped. Tick the consent checkbox before Import enables.

Mailchimp

Paste your Mailchimp API key (format: abc123...-us21 — the part after the last dash is the data center) and the Audience ID (Mailchimp Audience dashboard → Settings → Audience name and defaults → Audience ID). ContentFlows pulls all subscribed members.

ConvertKit

Paste your ConvertKit API key (Settings → Advanced → API Key). All confirmed subscribers are imported.

Common issues

  • Mailchimp 401 Unauthorized — API key is wrong or the account disabled it. Regenerate in Mailchimp → Account → Extras → API keys.
  • “No valid email addresses” — CSV parser didn't detect an email column. Confirm there is a header row and a column literally named email.
  • Import finishes instantly with 0 added — every row was already in your list. That's normal for re-runs.

Common issues

Token is invalid or expired

Access tokens expire. LinkedIn tokens last ~60 days. Facebook/Instagram Page tokens never expire when derived from a long-lived user token (follow the steps in the Facebook section exactly). Generate a new token and update it in Integrations.

Facebook: (#200) Permissions error on publish

By far the most common cause: the Page token is missing the pages_manage_posts scope. This scope is easy to miss in the permissions popup because Graph API Explorer doesn't enable it by default. Verify your token at the Access Token Debugger — if pages_manage_posts is not in the scopes list, regenerate the token starting from Step 4 of the Facebook guide and explicitly check that permission.

LinkedIn: invalid URN

The Member URN must start with urn:li:person: (for personal profiles) or urn:li:organization:(for Company Pages) followed by the account's unique ID. A plain numeric or alphanumeric string is not a valid URN on its own.

Insufficient permissions on LinkedIn

Your LinkedIn app does not have the Share on LinkedIn product approved, or the token was generated without w_member_social. Go back to step 3 of the LinkedIn guide, then regenerate the token.

Facebook: wrong Page ID

The Page ID is the numeric id field from /me/accounts, NOT the human-readable username in the Page URL. If you paste the username by mistake, posts will fail.

You must be an admin of the Facebook Page

The Facebook account that generated the token is not an Admin of the target Page. Ask the Page admin to generate the token themselves, or get yourself added as Admin at facebook.com → Page settings → Page roles.

Instagram: not a Business or Creator account

Personal Instagram accounts cannot use the Content Publishing API. Follow the conversion steps above.

Instagram: account not linked to a Facebook Page

Your Instagram Professional account is not connected to a Facebook Page. Go to Instagram Settings → Account → Linked Accounts → Facebook and complete the link.

YouTube: API quota exceeded

YouTube Data API has a default quota of 10,000 units/day, which is more than enough for ContentFlows metadata lookups. If you hit the limit, it's likely the same API key is being used elsewhere — create a dedicated key for ContentFlows.


Still stuck?

Contact supportwith the error message and which platform you're connecting. Include the step number where you got stuck.

Related