The short version: a Named Credential holds the endpoint and the authentication, so your Apex holds neither. The callout becomes callout:My_Service/path and the platform attaches the credentials. That is worth doing for one integration and non-negotiable for five, because the alternative is secrets in code and endpoints that differ per sandbox.
What it replaces
The version without one looks harmless until you count the problems:
HttpRequest req = new HttpRequest();
req.setEndpoint('https://erp.example.com/api/orders');
req.setHeader('Authorization', 'Bearer ' + SECRET);
The endpoint is hard-coded, so every sandbox calls production. The secret is in source control, or in a custom setting somebody can query. A Remote Site Setting has to exist separately and nobody remembers to add it. And rotating the credential means a deployment.
With a Named Credential the same call is:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:ERP_Fulfilment/api/orders');
No endpoint, no header, no secret, and no Remote Site Setting — the credential covers it. Point the credential at a different endpoint per environment and the code is identical everywhere.
The modern split: External Credential and Named Credential
What used to be one record is now two, and the separation is the point.
The External Credential holds the authentication: the protocol, the principal, and the secret. The Named Credential holds the endpoint and points at an External Credential.
That split means several Named Credentials can share one authentication — a sandbox and a production endpoint using the same OAuth app, or three services behind the same gateway, and rotating the secret happens once.
It also introduces the step people miss: a permission set must be given access to the External Credential’s principal. Without it the callout fails with an authentication error that says nothing about permissions, and the fix is in a place nobody thinks to look.
Choosing the authentication protocol
- OAuth 2.0 client credentials for server-to-server, where no user is involved. This is the right default for an integration, and the one to ask for when a vendor offers several.
- OAuth 2.0 with a named principal when every call should act as one service account.
- OAuth 2.0 per-user when calls must act as the person, and each user authorises once. Powerful, and it adds a failure mode: a user who has not authorised yet.
- Basic or custom headers for an API key. Legitimate when that is all the vendor supports. Keep the key in the External Credential rather than in code.
Whatever you pick, avoid the username-password OAuth flow. Salesforce is ending support for it, and integrations relying on it stop working rather than degrade. The dates are in the retirement tracker.
Setting one up without the usual two hours
- Create the External Credential first, with the protocol and a principal. Nothing works until this exists.
- Give a permission set access to that principal, and assign it to whoever runs the callout. Including the integration user. This is the step that causes most first-time failures.
- Create the Named Credential with the URL and a link to the External Credential.
- Decide whether to generate the Authorization header. Leave it on for standard flows. Turn it off when you are building the header yourself, or you will send two.
- Test from Execute Anonymous before wiring it into anything, so a failure is isolated.
When the callout fails, in the order to check
401 or 403 from the remote system. Usually the principal, not the endpoint. Check the permission set grants access to the External Credential and that the assignment reached the running user.
“Unauthorized endpoint” from Salesforce. The callout never left. A path outside the credential’s URL, or a redirect to a host the credential does not cover: Salesforce blocks both, and it is not the remote system talking.
It works for you and not for a scheduled job. Different running user, different assignment. Per-user credentials fail this way by design.
It works in the sandbox and not production. Credentials do not deploy with their secrets. The record arrives. The secret has to be entered again, and this is the single most common release-day surprise with them.
What still belongs in your code
The credential handles who you are, not what happens when the call fails. Timeouts, retries and idempotency are still yours, and a Named Credential makes none of that safer. It just stops the secret being the thing you deploy. The failure design is in design the retry before you write the callout.
Frequently asked
Do I still need Remote Site Settings? Not for endpoints a Named Credential covers. You still need them for callouts made the old way, which is a reason to convert them.
Can Flow use one? Yes, through External Services or an invocable Apex method. The credential is not Apex-specific.
Are the secrets visible to admins? They are write-only in the interface once saved, which is the point. Anyone who can edit the credential can replace the secret, so treat edit access as equivalent to holding it.
How do I move one between orgs? The metadata deploys. The secret does not. Plan a manual step per environment, and write it into the release checklist rather than discovering it on the day.
