Every external integration in Apex eventually hits the same problem: where do you put the base URL and the API key? Hardcoding them in Apex means a deployment every time they change. Storing them in Custom Settings is better, but you still write authentication header construction in every callout class. Named Credentials solve both problems — endpoint URL and authentication configuration live in Salesforce Setup, and Apex references them with a single callout: prefix on the endpoint string.
What Named Credentials Do
A Named Credential is a Salesforce metadata record that stores two things: the base URL of an external service and the authentication configuration used to connect to it. When Apex makes a callout using a Named Credential, Salesforce replaces the callout:CredentialName portion of the endpoint with the stored base URL and automatically appends the configured authentication header to the HTTP request.
The result is that no authentication logic appears in Apex code. The token, the Base64-encoded credentials, the OAuth bearer header — all of it is managed by Salesforce. The Apex class just makes the HTTP call:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:ExampleAPI/v2/accounts');
req.setMethod('GET');
HttpResponse res = new Http().send(req);
Salesforce looks up the Named Credential named ExampleAPI, replaces that portion with its stored base URL (for example, https://api.example.com), builds the full URL as https://api.example.com/v2/accounts, and injects the configured authorization header. None of this is visible in the Apex code.
Creating a Named Credential in Setup
Navigate to Setup → Security → Named Credentials (or search "Named Credentials" in the Quick Find box). Click New. The form asks for:
- Label and Name — the Name is what you reference in Apex as
callout:Name - URL — the base URL of the external service, including the protocol (
https://) - Identity Type — Named Principal (all users share the same credential) or Per User (each user authenticates individually)
- Authentication Protocol — the type of authentication the external service requires
- Credential fields — username/password for Basic, client credentials for OAuth 2.0, etc.
The Name field determines the callout: prefix. A Named Credential named Stripe_API is referenced in Apex as callout:Stripe_API/charges. Changing the Name would require code changes. Choose a descriptive, stable name at creation time.
Authentication Protocols
| Protocol | When to Use | What Salesforce Does |
|---|---|---|
| No Authentication | Public APIs, IP-restricted endpoints, API key in URL path | Sends no auth header — only resolves the base URL |
| Basic Authentication | Endpoints requiring username:password | Encodes username:password in Base64, injects Authorization: Basic header |
| OAuth 2.0 | Modern APIs with token-based auth (client credentials or auth code flow) | Acquires access token, caches it, refreshes on expiry — fully automatic |
| JWT Token | APIs using signed JWT assertions | Constructs and signs the JWT using configured private key, injects as Bearer |
| AWS Signature V4 | AWS services (S3, API Gateway, etc.) | Constructs the AWS SigV4 signature headers per AWS specification |
| Custom (Auth Provider) | Non-standard flows, token exchange patterns | Delegates to a custom Auth Provider class — full flexibility |
OAuth 2.0 Named Credentials
For OAuth 2.0 credentials, the flow Salesforce uses depends on the Identity Type and the OAuth grant type configured:
- Client Credentials flow (machine-to-machine) — Salesforce sends the client ID and secret to the token endpoint, receives an access token, and caches it. When the token expires, Salesforce automatically requests a new one. No user action required.
- Authorization Code flow — requires a user to authorise access once. After the initial auth, Salesforce stores and refreshes the token. Used with Identity Type = Per User.
Once OAuth 2.0 is configured, the Apex callout requires no authentication code at all. The bearer token appears in the HTTP request without being visible in code, logs, or version control.
External Credentials (Winter '23 and Later)
Salesforce separated authentication from endpoint configuration starting in Winter '23. The modern approach uses two records instead of one:
- External Credential — stores the authentication configuration (OAuth app, JWT keys, Basic credentials). Think of it as the auth identity.
- Named Credential — stores the endpoint URL and references an External Credential for authentication.
This separation enables two things the legacy single-record model could not do cleanly. First, you can reuse one External Credential across multiple Named Credentials — useful when the same OAuth app connects to multiple endpoints. Second, per-user authentication works properly: each user authenticates once through the External Credential's connected app, and their individual token is used when they trigger a callout.
// Legacy single-record model (still works)
// Setup → Named Credentials → URL + Auth in same record
req.setEndpoint('callout:LegacyCredential/path');
// Modern two-record model
// External Credential: auth config (OAuth app, tokens)
// Named Credential: endpoint URL + reference to External Credential
req.setEndpoint('callout:ModernCredential/path');
// Apex code is identical — the difference is in Setup
Per-User vs Named Principal
The Identity Type on a Named Credential determines whether all users share one credential or each user has their own:
| Identity Type | Behaviour | Use Case |
|---|---|---|
| Named Principal | One shared credential for the entire org. All callouts use the same URL, same token, same identity. | Service-to-service APIs, webhooks, batch integrations where user identity is irrelevant |
| Per User | Each user authenticates individually. Callout uses the running user's personal token. Users must complete OAuth authorisation once via the Authentication Settings for External Systems page in their profile. | APIs where user identity matters — user-specific data, audit trails, delegated permissions |
Per-User credentials require the user to have completed the initial OAuth flow. If a user triggers a callout before authenticating, the callout fails with an authentication error. For automated flows (batch, scheduled, future methods), Per-User credentials are generally not appropriate — use Named Principal there.
Named Credentials vs Custom Settings for URLs
A common alternative to Named Credentials is storing the base URL in a Custom Setting or Custom Metadata. This avoids hardcoding and allows environment-specific URLs without deployment. But it requires manual authentication header construction in every callout class:
// Custom Settings pattern — URL managed, but auth manual
API_Config__c config = API_Config__c.getInstance();
HttpRequest req = new HttpRequest();
req.setEndpoint(config.Base_URL__c + '/v1/records');
req.setHeader('Authorization', 'Bearer ' + config.API_Token__c);
// Token value is in the database in plaintext
// No automatic refresh if token expires
// Named Credential pattern — URL and auth managed by Salesforce
req.setEndpoint('callout:MyAPI/v1/records');
// No auth header construction — Salesforce handles it
// Token never appears in code or database
Use Named Credentials when you need authentication management. Use Custom Metadata for non-credential configuration values (feature flags, thresholds, labels) that do not involve credentials.
Allowed Remote Sites
Salesforce requires all external endpoints to be on the Remote Site Settings allowlist before a callout can be made. When you create a Named Credential, Salesforce automatically adds its URL to the Remote Site Settings. You do not need to manage this separately — it is handled at creation time.
For callouts made to raw URLs (without Named Credentials), you must manually add the domain to Setup → Security → Remote Site Settings. This is one of the common debugging steps when a new callout fails: verify the domain appears in Remote Site Settings.
Merge Fields in Named Credentials
Named Credentials support merge fields in certain configuration fields, allowing dynamic values at runtime. Common uses:
{!$User.Email}— pass the running user's email as a header value{!$User.Id}— pass the Salesforce user ID to identify the caller{!$Organization.Id}— pass the org ID for multi-tenant external services
These merge fields are evaluated at callout time, so the value reflects the current transaction context. They are configured in the Named Credential's header mapping fields, not in Apex code.
Testing Apex Callouts That Use Named Credentials
Testing works identically to any other Apex callout test. The mock intercepts the callout before Salesforce attempts to resolve the Named Credential — no external contact, no credential lookup:
public class ExternalAPIMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest req) {
HttpResponse res = new HttpResponse();
res.setStatusCode(200);
res.setHeader('Content-Type', 'application/json');
res.setBody('{"id":"rec001","status":"active"}');
return res;
}
}
@IsTest
static void testCalloutWithNamedCredential() {
Test.setMock(HttpCalloutMock.class, new ExternalAPIMock());
Test.startTest();
String result = ExternalService.getRecord('rec001');
Test.stopTest();
System.assertEquals('active', result, 'Status should be active');
}
The mock does not need to know whether the code uses a Named Credential or a raw URL. Test.setMock() intercepts any Http.send() call, regardless of how the endpoint was constructed.
Deploying Named Credentials
Named Credentials are metadata and deploy with standard Salesforce deployment tools — Change Sets, SFDX, Metadata API. The metadata type is NamedCredential. One important security consideration: when you deploy a Named Credential via metadata, the credential values (passwords, tokens) are not included in the deployment package. You must configure the credential values manually in Setup after deployment in each target org.
This is intentional — it prevents credentials from appearing in version control. Plan your deployment process to include a post-deployment step where an admin enters the credential values in each target environment.
Credential values do not travel with deployments. After deploying a Named Credential to a sandbox or production, an admin must open the Named Credential in Setup and enter the URL and authentication values for that environment. The code deploys; the secrets are entered manually.
For earlier context on how Named Credentials are used in callouts, see Session 75: HTTP Callouts in Apex — REST and SOAP Integration. For the async patterns that typically invoke these callouts from triggers, see Session 56: Queueable Class in Apex.
Frequently Asked Questions
What is a Named Credential in Salesforce?
A Named Credential is a Salesforce Setup configuration that stores an external service's endpoint URL and authentication details in one place. In Apex, reference it as callout:CredentialName/path. Salesforce resolves the base URL, injects the auth header, and handles token refresh automatically. Credentials never appear in code, logs, or version control.
How do you use a Named Credential in Apex?
Set the endpoint using the callout: prefix and the credential name: req.setEndpoint('callout:MyAPICredential/v1/records'). Salesforce replaces callout:MyAPICredential with the stored base URL and injects the authentication header. No additional auth code is needed — no tokens, no Base64 encoding, no header construction in Apex.
What authentication protocols do Named Credentials support?
Named Credentials support No Authentication, Basic Authentication, OAuth 2.0 (client credentials, authorization code, JWT Bearer — with automatic token refresh), JWT Token, and AWS Signature Version 4. Custom flows are supported via Auth Providers. For OAuth 2.0 specifically, Salesforce handles token acquisition, storage, and refresh entirely — no code required.
What is the difference between Named Credentials and External Credentials?
External Credentials (Winter '23+) separate authentication from the endpoint URL. An External Credential stores the authentication configuration (OAuth app, JWT keys, Basic credentials). A Named Credential stores the endpoint URL and references an External Credential. This separation allows one authentication config to serve multiple Named Credentials, and enables proper per-user OAuth flows where each user's individual token is used for their callouts.
How do you test Apex callouts that use Named Credentials?
Identically to any other callout test. Implement HttpCalloutMock with a respond() method that returns a constructed HttpResponse. Register it with Test.setMock(HttpCalloutMock.class, new YourMock()) before the callout runs. Salesforce does not resolve the Named Credential or contact the external service during test execution — the mock intercepts the Http.send() call regardless of how the endpoint was constructed.