Not verified hands-on. This article was written from primary documentation rather than reproduced in an org, so it carries no tested-release badge. If you run it and something differs, say so in the comments and it gets tested and corrected.

External Client Apps are the replacement for Connected Apps. They run the same OAuth flows against the same endpoints, so nothing your client code does needs to change. Build new integrations on them. Leave working Connected Apps alone unless you have a specific reason, because there is no forced cutover and migration means reissuing credentials.

What actually changed

A Connected App is one record holding everything: the OAuth settings, the consumer key and secret, the callback URL, the scopes, the session policies, the permitted user list. That single record is why packaged Connected Apps behaved so badly. A publisher could not change the app after release without stepping on whatever the subscriber admin had configured, so most ISVs simply never updated theirs.

An External Client App splits that record into separate pieces of metadata:

  • The app itself holds the name, description, contact email and distribution state.
  • Global OAuth settings hold the consumer key, the secret, the callback URL and the requested scopes. These belong to whoever built the app.
  • Configurable policies hold refresh token policy, IP relaxation, permitted users and session requirements. These belong to the admin installing it.

Because ownership is split, a publisher can ship a new version that changes the OAuth configuration without overwriting the local policy, and an admin can tighten policy without breaking on the next upgrade. That is the whole argument, and it is a good one.

Where you find them

Setup has a separate node, External Client App Manager, alongside the old App Manager. The distribution state matters: Local means the app exists only in this org, Packaged means it can be included in a second-generation package and shipped. You choose at creation and it is not a casual switch afterwards.

In source form you will see several files rather than one:

force-app/main/default/
  externalClientApps/My_Integration.eca-meta.xml
  extlClntAppGlobalOauthSettings/My_Integration.ecaGlblOauth-meta.xml
  extlClntAppOauthSettings/My_Integration.ecaOauth-meta.xml
  extlClntAppOauthConfigurablePolicies/My_Integration.ecaOauthPlcy-meta.xml

Retrieve them the same way as anything else:

sf project retrieve start --metadata ExternalClientApplication:My_Integration --target-org prod

What is identical

The OAuth flows are unchanged. Web server, JWT bearer, client credentials, device flow, token exchange: same endpoints, same request shapes, same scope names. A client library that talks to a Connected App talks to an External Client App with no code change once you swap the consumer key.

PKCE, the callback URL rules, the “Admin approved users are pre-authorised” model and profile or permission set assignment all work the way you already know. Consumer key and secret still live on the app and still need protecting.

The migration question

Answer it with a question of your own: is this app packaged?

If it ships in a managed package, the case for moving is strong. Upgradeable OAuth configuration removes a permanent support burden, and every subscriber install after the change gets it.

If it is a local app doing server-to-server work inside one org, the case is weak. Migration is not an in-place conversion. You create the External Client App, it gets a new consumer key and secret, and every client using the old credentials has to be updated in a coordinated window. For an integration with three callers in two environments that is an afternoon. For one with an unknown number of callers, check Login History first and find out who is actually using it before you plan anything.

What to do for new work

Use an External Client App unless something specific blocks you. Some older or more specialised configurations still only exist on Connected Apps, and if you hit one, the fallback costs nothing today. Salesforce has said Connected Apps remain supported, and has separately been tightening who is allowed to create them at all, which is a sensible change either way.

Whichever you create, narrow the scopes at creation rather than promising yourself you will do it later. Scope changes after go-live need every client to re-authorise, and that is the same outage window whichever object type you are editing.

Frequently asked

Do my existing Connected Apps stop working? No. There is no announced retirement date and existing apps continue to authenticate normally.

Can one org have both? Yes, and most do. They appear in different Setup nodes and do not conflict.

Does a Named Credential care which I use? No. An External Credential configured for OAuth points at either one by consumer key and secret.

Can I keep the same consumer key when migrating? No. Plan the credential swap as part of the work rather than hoping for an in-place upgrade.