MetaSync for Confluence — Documentation
Living Salesforce documentation in Confluence

← Documentation home

Getting started


What is MetaSync?

MetaSync keeps documentation of your Salesforce org inside Confluence and refreshes it on the schedule you set. It reads your org’s metadata — objects, fields, Flows, profiles, permission sets, validation rules, Apex, reports and more — and turns it into structured, readable Confluence pages that are re-synced automatically, so the documentation tracks the org without anyone writing it by hand. Each page is a point-in-time snapshot of its last sync — it shows the date it was last synced, so readers can see how current it is.

Note — Metadata, not data. MetaSync reads your org’s configuration (its structure and rules), never your business records. The connection is one-way and read-only: Salesforce is only ever read, never written to. (Custom Metadata Type records are the one exception — see The one exception: Custom Metadata Type records.)

Who it’s for

The three places you’ll use it

How it works

  1. An administrator connects a Salesforce org to MetaSync using OAuth — a one-way connection MetaSync uses only to read metadata.
  2. A scheduled sync engine extracts the org’s metadata using the Salesforce APIs.
  3. MetaSync transforms that metadata and publishes structured Confluence pages — creating new pages and updating existing ones so nothing is ever duplicated.
  4. On a schedule, MetaSync re-syncs and refreshes the pages, so the documentation tracks the org over time. See How syncing works.

How the pieces fit together

Figure: broker-architecture — One-way by design: MetaSync brokers between the two systems — Salesforce is only ever read, and pages are only ever written to Confluence. The two never talk to each other directly. (illustrated in the in-app documentation).

Note — Where to go next. New to MetaSync? Start with Onboarding: from install to first sync. Want the full picture of what it produces? See Overview dashboard and Reading your documentation space.


Onboarding: from install to first sync

This is the end-to-end path from installing MetaSync to seeing your first pages in Confluence. Setup is done by a Confluence administrator — or by someone the administrator gives the App admin role under Connections → Additional access, which is the usual answer when the Confluence admin doesn’t administer Salesforce: the person who does can run the whole connection setup without becoming a site admin. An admin can also grant named users or groups plain read-only access (see Connected Salesforce Org); everyone else sees a friendly notice instead. The published documentation pages remain available to everyone with access to the space.

Note — Before you start. You’ll need administrator access in Confluence, and an OAuth app in the Salesforce org you want to document — an External Client App (or an existing Connected App) whose Consumer Key and Consumer Secret you paste into MetaSync. MetaSync requests only the api scope, plus refresh_token / offline_access when a person signs in — what the connection can see is controlled by the integration user’s Salesforce permission set, not by broad scopes.

Note — Pick the connection method first. Step 1 of the connect dialog opens with a Connection method choice, and it decides how you set the Salesforce app up. Client Credentials Flow (recommended; Salesforce also describes it as its server-to-server integration flow) has the app’s key and secret sign in as a Run As user you name in Salesforce: no login prompt, no person in the loop, and nothing to expire. Web Server Flow has someone sign in once as the integration user, and MetaSync keeps a refresh token. Both end up acting as the same locked-down user. Each has its own recipe below — follow one.

Create the External Client App in Salesforce

MetaSync signs in through an OAuth app that lives in your org — you create it once, then paste its Consumer Key and Secret into MetaSync. Salesforce’s current app type is the External Client App. A Connected App works identically if your org already has one you can reuse, but new Connected Apps can no longer be created in most orgs (Salesforce disables that by default from Spring ‘26 — the New Connected App button is greyed out unless Salesforce Support has unlocked it), so create an External Client App. Follow the recipe for the connection method you picked.

  1. Setup → Quick Find → External Client App Manager → New External Client App. Name it (e.g. MetaSync for Confluence), enter a contact email, and set Distribution State to Local.
  2. Enable OAuth (under API (Enable OAuth Settings)) and select the Manage user data via APIs (api) scope — nothing else. This method never opens a login page, so MetaSync’s Callback URL is not part of it; if Salesforce insists on a value in the Callback URL field, any URL your org accepts will do, because this flow never redirects anywhere.
  3. Tick Enable Client Credentials Flow under Flow Enablement in the same OAuth settings. This is the setting that lets the app’s key and secret be exchanged for a token directly; Salesforce shows a Confirm Enablement of the Client Credential Flow warning — read it, click OK — then click Create. The Policies tab only appears once the app exists.
  4. Policies → Edit → OAuth Flows and External Client App Enhancements: tick Enable Client Credentials Flow here too (the policy has its own checkbox), type the integration user’s username into Run As (Username), and Save. Until this policy is saved, a token request fails with invalid_grant — no client credentials user enabled. Every token minted through this flow acts as that user, so that user’s permission set is the whole boundary. An API-only Integration User licence works here. Salesforce’s Permitted Users policy does not apply to the Run As user, so this setting is what bounds the flow.
  5. Settings → OAuth Settings → Consumer Key and Secret — it opens in a new browser tab, and Salesforce asks you to verify your identity with an emailed code before showing the values. Copy both.
  6. Copy the org’s My Domain URL from Setup → My Domain: https://<name>.my.salesforce.com. The token request for this flow goes to your org’s own address — Salesforce does not accept login.salesforce.com or test.salesforce.com for it, and MetaSync refuses them with the reason under the field.
  7. Optional: Policies → OAuth Policies → Edit — set IP Relaxation to Relax IP restrictions if your org enforces login IP ranges, since MetaSync’s calls come from Atlassian’s cloud, whose addresses vary.

Warning — The key and secret are the credential. While the Client Credentials Flow is enabled, anyone holding the Consumer Key and Secret can mint tokens at the Run As user’s permission level. Store them the way you store any production secret, and give the Run As user the least-privilege permission set below so a leaked pair buys nothing beyond read access to configuration. Rotating the secret cuts MetaSync’s access at its next token request — see The integration user.

Recipe B — Web Server Flow

  1. Setup → Quick Find → External Client App Manager → New External Client App. Name it (e.g. MetaSync for Confluence), enter a contact email, and set Distribution State to Local.
  2. Enable OAuth (under API (Enable OAuth Settings)). Callback URL: get it from MetaSync before you fill this in. Open the MetaSync admin page, choose Connect org, set the Connection method to Web Server Flow, and the Callback URL appears above the Consumer Key field with a Copy button. It is fixed for your installation and doesn’t depend on the app you’re creating, so copy it now and paste it here. Keep that dialog open — you come back to it with the keys.
  3. OAuth scopes: select Manage user data via APIs (api) and Perform requests at any time (refresh_token, offline_access) — nothing else.
  4. Security and flow settings: keep Require Proof Key for Code Exchange (PKCE) on (MetaSync uses PKCE); keep Require secret for Web Server Flow and Require secret for Refresh Token Flow on (MetaSync sends the secret). Refresh Token Rotation may be on or off: MetaSync stores each rotated token as Salesforce issues it and re-reads the newest stored one before every refresh, so both settings work.
  5. Click Create, then open Settings → OAuth Settings → Consumer Key and Secret — it opens in a new browser tab, and Salesforce asks you to verify your identity with an emailed code before showing the values. Copy both.
  6. Policies → OAuth Policies → Edit: Permitted Users — choose Admin approved users are pre-authorized and assign the integration user’s profile or permission set to the app. The alternative, All users can self-authorize (the default), lets anyone in the org who holds the Consumer Key and Secret authorise this app as themselves and receive an api-scoped token at their own permission level, which defeats the least-privilege setup below; it is fine for a quick sandbox trial, but tighten it before you connect production. When you save this choice Salesforce asks you to Confirm permitted user policy — click OK. Refresh Token Policy — Refresh token is valid until revoked if it is offered; when the app’s Enforce Refresh Token TTL setting is on (the default on new apps) Salesforce offers expiry choices instead, and the default — expire an unused token after 30 days — is fine, because MetaSync refreshes far more often than that; IP Relaxation — Relax IP restrictions if your org enforces login IP ranges (MetaSync’s calls come from Atlassian’s cloud, whose addresses vary). Save.

Note — Salesforce Setup labels. The labels above are Salesforce’s at the time of writing; Salesforce moves them between releases. If a setting isn’t where this page says, search Setup for the setting name — what matters is the settings themselves: OAuth on with the api scope, and then either the Client Credentials Flow enabled with a Run As user, or PKCE with the secret required on both flows.

The integration user (least privilege)

Both methods act as one Salesforce user, and that user’s permissions define what MetaSync can read — so point them at a dedicated integration user. On Client Credentials Flow, that user is the one you name as Run As on the app’s Client Credentials Flow policy. On the sign-in method, it is the user you sign in as when MetaSync opens the Salesforce login tab: the refresh token belongs to whoever authorizes. MetaSync never writes to Salesforce and never queries business records, so the permission set needs no object permissions at all — not Read, and not Create, Edit or Delete, on any standard or custom object. Leave Object Settings empty and grant only the user permissions below: granting Read ‘just to be safe’ is what weakens the guarantee, because Read passes Salesforce’s object-level check and leaves only your sharing model in the way (see Why the integration user cannot read records). Start from a permission set with:

Note — MetaSync documents what the integration user can see. Custom fields the user has no field-level access to are still captured from Salesforce’s field definitions and flagged No FLS on the page. Whole components the user can’t read are named on the type’s index page in a not captured — no access panel — that panel is your signal that a user permission is missing — usually Modify Metadata Through Metadata API Functions for layouts and the other retrieve-based types, or Author Apex for Apex source. Add the permission and re-sync; it is never fixed by granting Read on an object. See Why is a component or type missing? and The integration user.

Connect MetaSync

  1. Install MetaSync from the Atlassian Marketplace into your Confluence site. A new global MetaSync page becomes available.
  2. Open the MetaSync admin page. As a Confluence administrator — or as a user holding the App admin role — you’ll see the full dashboard; app admins see everything except the Additional access card. A user granted read-only access sees a reduced version; anyone else is told the app is managed by admins.
  3. Step 1 of 3 — Salesforce app. Click Connect org. The step opens with the Connection method: Client Credentials Flow (recommended), where the app’s key and secret sign in as the Run As user with no login prompt and nothing to expire, or Web Server Flow, where a person signs in as the integration user and MetaSync keeps a refresh token. On Client Credentials Flow there is no Callback URL and no org type — paste the org’s My Domain login URL (https://<name>.my.salesforce.com, from Setup → My Domain), the Consumer Key, the Consumer Secret and a display name; login.salesforce.com and test.salesforce.com are refused for this method, with the reason shown under the field. On Web Server Flow the Callback URL with its Copy button sits above the Consumer Key field — that is the value your app’s OAuth settings need — and you pick the org type: Production / Developer (login.salesforce.com), Sandbox (test.salesforce.com), or My Domain URL for an org whose My Domain policy blocks the shared login page (see the callout below). Either way, click Next: Confluence destination.
  4. Step 2 of 3 — Confluence destination. Choose the Confluence space to publish into, the Home page title (default MetaSync Home) that roots the tree, the page structure (per component or per type — see Page structure: per type vs per component) and whether to include managed-package components. A live page-tree preview shows what you’ll get. The button reads Next: Connect on Client Credentials Flow and Continue to Salesforce login on Web Server Flow.
  5. Step 3 of 3, on Client Credentials Flow — connect. Click Test and connect. MetaSync exchanges the key and secret for a token at your My Domain URL, checks it can read the org, and on success shows the org name and the Run As user it signed in as — confirm that is the integration user you meant. There is no Salesforce popup and no identity-verification email, and the destination you chose in step 2 is saved as the connection completes. If Salesforce refuses the exchange, the two messages you can see are explained in The Salesforce login fails or shows an error.
  6. Step 3 of 3, on Web Server Flow — authorize. MetaSync repeats the Callback URL as a reminder, then click Open Salesforce login. Sign in as the integration user, not as yourself — the refresh token belongs to whoever authorizes. Two things to have ready first: if that user is on the Salesforce Integration licence, assign the Salesforce API Integration permission set licence to them before you get here, or Salesforce refuses to assign the MetaSync permission set at all; and expect Salesforce to show Verify Your Identity and email a code to the integration user on this first sign-in, because the login arrives from Atlassian’s cloud rather than a known device — so that user’s mailbox has to be one you can read. See The integration user. After you authorize, MetaSync stores a refresh token so future syncs re-authenticate on their own — you don’t repeat the login. The destination you chose in step 2 is saved as the connection completes.
  7. Select the metadata scope (optional). On the Metadata types tab, toggle which types — Flows, Profiles, Permission Sets, Validation Rules, Reports and more — MetaSync documents. Everything is on by default, so you can skip this and narrow it later. See Metadata Types & scope.
  8. Run your first sync. Connecting does not start a sync. Click Sync now in the header bar; MetaSync queues the run and it starts within about five minutes.
  9. Watch the pages appear. MetaSync publishes a home page, a category index page for each included type, and detail pages for the components — creating and updating pages in your chosen space.

Note — If your org blocks login.salesforce.com. This one is about the sign-in method; Client Credentials Flow always uses your My Domain URL, so it sidesteps the problem entirely. Some orgs turn on Prevent login from https://login.salesforce.com under Setup → My Domain → Policies, so the shared login page refuses them. Choose My Domain URL as the org type and paste the org’s own login URL from Setup → My Domain: https://<name>.my.salesforce.com for production or Developer Edition, https://<name>--<sandbox>.sandbox.my.salesforce.com for a sandbox. Only Salesforce login hosts are accepted — a Lightning (lightning.force.com) or Experience Cloud address is refused with a hint under the field. MetaSync saves the login URL with the connection and reuses it whenever you re-authorize, so you enter it once. The error codes Salesforce can show at login are explained in The Salesforce login fails or shows an error.

Note — The first sync of a large org runs in stages. MetaSync’s sync engine runs in five-minute cycles, and a big org’s first sync is spread across several of those cycles so it always finishes within each cycle’s time budget. You can keep working while it runs — see How syncing works for what happens on each cycle.

Warning — If the destination doesn’t get saved. MetaSync can’t publish until a Confluence destination space is set. If the space can’t be saved as the connection completes, you get an error toast (“Destination not set”) rather than a clean success — the org is connected but has nowhere to publish. The usual cause is Confluence permissions: the MetaSync app user has no permission on the space you picked, so the write is refused. Check Space settings → Permissions for that space and give the app user (or the group it belongs to) space and page permissions, and check whether an org-level app access rule restricts which spaces apps may write to. Then open Connections, choose Edit destination, pick the space again, and run a sync.

Note — Trouble connecting?. If the Salesforce connection is later rejected, MetaSync says so and offers the repair that fits the method: a Re-authorize Salesforce prompt for a sign-in connection, which reuses the app keys already saved with it, or Update app keys for a Client Credentials Flow one. See Re-authorizing your Salesforce org and Permissions, scopes & data handling.


Reading your documentation space

Once a sync completes, MetaSync builds a tidy page tree in your chosen Confluence space. Every page is created or updated in place — re-running a sync refreshes existing pages rather than making duplicates.

The page hierarchy

Note — Page structure is configurable. The detailed tree above is the default (a page per component). You can instead choose a flatter, index-only structure where every component is listed on its category index and per-component pages are skipped. See Page structure: per type vs per component.

Pages carry descriptive titles (for example an object page uses its label and API name, a validation rule uses VR: <name>). Where one component references another — a Flow that runs on an object, a field that looks up another object, an Apex class’s referenced objects and fields — MetaSync renders those references as clickable links to the other component’s page wherever the target page exists, so you can navigate the org’s structure by following the dependencies. Components that MetaSync doesn’t have a page for appear as plain code text instead.

Detail pages also surface computed insights beyond the raw metadata — for example documentation coverage on an object, a “Referenced by” list of what depends on a component, and PII/classification badges on fields when your org uses Salesforce Data Classification. See PII & data classification.

Note — Field-level reference. For a page-by-page breakdown of exactly what each metadata type’s page contains, see the metadata reference (and the per-type entries such as Fields and Flows).

Warning — Some sections are truncated on very large components. To keep pages readable, long lists (for example a very large object’s related objects, or a long “Referenced by” list) are capped and MetaSync adds a note saying how many items were shown out of the total. See Truncation & display limits.


Managed regions & team annotations

MetaSync-generated content lives inside a managed region on each page. On every sync, MetaSync replaces only what’s inside that region — so your team’s own notes, kept outside it, survive re-syncs untouched. This is what lets auto-generated documentation and human context coexist on the same page.

How the region is marked

MetaSync wraps its generated content between hidden <!-- METASYNC:BEGIN --> and <!-- METASYNC:END --> markers. Because Confluence Cloud can silently strip hidden HTML comments when a page is edited, MetaSync also uses a visible heading as the reliable boundary: the Team Notes heading (or, if that one is gone, a Team annotations heading). Everything from the earliest of those headings downward is treated as your content and is never overwritten. When a page is first created, MetaSync adds the managed region followed by a Team Notes section containing the note “Add team-specific notes here — MetaSync will not overwrite this section.”

Tip — Two ways to keep your own notes. Below the Team Notes heading MetaSync also seeds a Team annotations table (Owner, Compliance, Last reviewed, Notes) — once, when the page is created, and never rewritten afterwards. It sits outside the managed region, so your edits to it survive every sync. Use it for structured ownership metadata, and the free-form Team Notes area for longer context.

Adding team notes safely

  1. Open the Confluence page and edit it as normal.
  2. Add your content below the Team Notes heading, at the bottom of the page. Anything from that heading down is preserved across syncs.
  3. Save. On the next sync, MetaSync refreshes only the generated part above and leaves your Team Notes exactly as written.

Warning — Edits inside the generated region are replaced. Any changes you make to the auto-generated content itself (above the Team Notes heading) will be overwritten on the next sync. Put anything you want to keep in the Team Notes section, or in the Team annotations table.

What happens if the markers or heading are deleted

MetaSync looks for a Team Notes or Team annotations heading first (lightly edited headings still match), then falls back to the hidden BEGIN/END markers. If it can find none of them — for example if both headings and the markers were removed from a page — MetaSync can no longer tell your content apart from its own, so it replaces the whole page body with freshly generated content and re-adds a clean Team Notes placeholder. To avoid losing manual notes, keep the Team Notes heading in place.

Tip — If MetaSync can’t read a page, it doesn’t touch it. Updating a page means reading its current body first, to find where your content starts. If that read fails (a transient Confluence error or timeout), MetaSync skips the update entirely and logs why, rather than writing generated content over a body it couldn’t see — which would have erased the page’s Team Notes. The page is retried on the next sync. The same rule applies when a page needs re-parenting.

Note — Related. For how and when re-syncs run (and therefore when your pages get refreshed), see How syncing works. For more onboarding context, see Onboarding: from install to first sync and Reading your documentation space.