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:

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

ProtocolWhen to UseWhat Salesforce Does
No AuthenticationPublic APIs, IP-restricted endpoints, API key in URL pathSends no auth header — only resolves the base URL
Basic AuthenticationEndpoints requiring username:passwordEncodes username:password in Base64, injects Authorization: Basic header
OAuth 2.0Modern APIs with token-based auth (client credentials or auth code flow)Acquires access token, caches it, refreshes on expiry — fully automatic
JWT TokenAPIs using signed JWT assertionsConstructs and signs the JWT using configured private key, injects as Bearer
AWS Signature V4AWS services (S3, API Gateway, etc.)Constructs the AWS SigV4 signature headers per AWS specification
Custom (Auth Provider)Non-standard flows, token exchange patternsDelegates 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:

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:

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 TypeBehaviourUse Case
Named PrincipalOne 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 UserEach 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:

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.