Callout, Apex
An Apex Callout is an outbound HTTP request that Apex code sends to a system outside Salesforce, typically a REST or SOAP API.
Definition
An Apex Callout is an outbound HTTP request that Apex code sends to a system outside Salesforce, typically a REST or SOAP API. The callout runs from inside the Salesforce platform, hits an external endpoint, and parses the response into Apex objects that the rest of the code can act on. Callouts are how Salesforce integrates with payment processors, ERP systems, identity providers, AI models, and any third-party service that exposes an HTTP API.
The platform restricts callouts heavily. They cannot fire from inside a database trigger synchronously (must be queued via @future, Queueable, or platform events), they require a Remote Site Setting or a Named Credential allowlist, they count against per-transaction governor limits (100 callouts per Apex transaction, 120-second total callout time), and they must use HTTPS in production unless the endpoint is explicitly exempted. Every restriction exists to keep the multi-tenant platform from becoming an attack surface or a runaway resource consumer.
How Apex callouts integrate Salesforce with the outside world while respecting platform constraints
The HttpRequest, Http, and HttpResponse pattern
Every callout follows the same three-class pattern. HttpRequest holds the URL, method, headers, and body. Http is the dispatcher; you call its send method passing the HttpRequest. HttpResponse holds the status code, headers, and body of the reply. Parse the response body as JSON or XML using Apex's JSON.deserializeUntyped or a typed wrapper class. The pattern is deliberately verbose; there is no fluent builder for callouts in Apex.
Named Credentials versus Remote Site Settings
Salesforce requires every outbound endpoint to be allowlisted. Two options. Remote Site Settings: a simple URL allowlist. Named Credentials: URL allowlist plus authentication metadata (OAuth tokens, API keys, certificates) plus URL templating. Named Credentials are the modern path; Remote Site Settings is the legacy path that only matters when the integration does not need credentials. Hardcoding credentials in Apex source is a security anti-pattern; Named Credentials store the secret outside the codebase.
The trigger callout restriction and async patterns
Synchronous callouts cannot fire from a database trigger. The platform forbids holding a database transaction open while waiting for an external HTTP response, because a slow endpoint would hold row locks for seconds. Three async patterns work around this: @future(callout=true) for fire-and-forget, Queueable Apex for chained async with state, and platform events for event-driven integration. Each has its own limits; @future is capped at 50 calls per transaction, Queueable supports chaining but adds latency, platform events scale highest but require subscriber infrastructure.
Governor limits on callouts
Per-transaction limits constrain callouts. The platform allows 100 callouts per synchronous transaction, 200 for async, and a total callout time of 120 seconds aggregated across all callouts in the transaction. Each individual callout has a default timeout of 10 seconds, configurable up to 120 seconds. The aggregate cap is what trips people up; a transaction making 30 callouts at 4 seconds each is at 120 seconds and the 31st fails. Bulkification matters even for HTTP work: batch related requests when the endpoint supports it.
Mock callouts in test classes
Apex tests cannot make real callouts; the platform routes them through a mock framework. Implement HttpCalloutMock (single mock) or a multi-endpoint dispatcher that switches mock response by URL. Test classes call Test.setMock(HttpCalloutMock.class, new MyMockResponse()) before invoking the code under test. Without a mock the test fails with You have uncommitted work pending or Methods defined as TestMethod do not support Web service callouts. This is the single most common Apex test failure on integration code.
Certificate authentication and two-way TLS
Some integrations require mutual TLS where Salesforce presents a client certificate. Generate the certificate in Setup, Certificate and Key Management, export the CSR for the endpoint owner to sign, import the signed certificate back into Salesforce, and reference it on the Named Credential. The platform handles the TLS handshake automatically. Self-signed certs cannot be used in production; Salesforce only trusts certificates signed by a recognized CA.
Long-running callouts and the Continuation framework
For callouts that legitimately take longer than the 120-second transaction cap, the Continuation framework releases the Apex thread while waiting for the response. The user's request returns control to the browser, the platform parks the transaction, the response triggers a continuation method when it arrives. Continuations are designed for Visualforce and LWC requests; they do not work in triggers, batch, or scheduled Apex. Use sparingly; the user-facing pattern feels async but the developer experience is more complex than a normal callout.
Writing a clean Apex callout from setup to deployable code
Building a callout is half code, half configuration. Set up the Named Credential, write the callout code, write the mock-backed tests, and deploy. The order matters; production deploys fail if the Named Credential is not in the deploying metadata package.
- Create a Named Credential
Setup, Quick Find, Named Credentials. New Named Credential. Set the URL, authentication type (Password, OAuth, AWS Signature), and the External Credential (a separate record that stores the actual secret). Named Credentials replace older Auth Provider plus Remote Site Setting setups.
- Write the callout method
Build the HttpRequest, set the endpoint to callout:Named_Credential_Name/path, set headers and body, call new Http().send(request). Parse the response with JSON.deserialize or a typed wrapper class. Keep the method @AuraEnabled or @InvocableMethod if calling from LWC or Flow.
- Handle errors and retries
Check response.getStatusCode() before parsing. Implement retry logic with exponential backoff for 5xx responses. Log every 4xx to a custom error log object for support visibility. Do not silently swallow errors; surface them in a way operators can find.
- Build the mock test class
Implement HttpCalloutMock with a respond method that returns a hardcoded HttpResponse. Test.setMock(HttpCalloutMock.class, new YourMock()) inside the test. Assert on parsed data and on error paths separately.
- Bulkify and async
If the calling context is a trigger, wrap the callout in @future(callout=true) or a Queueable. Pass record IDs through, query inside the async context, not record objects across the async boundary. Async methods cannot return values to the caller; persist results to a custom object or platform event.
GET, POST, PUT, PATCH, DELETE. PATCH is supported but some older REST endpoints reject it; POST with an X-Method-Override header is the workaround.
Default 10 seconds, configurable up to 120 seconds per callout. The aggregate cap of 120 seconds across all callouts in a transaction is what limits total work.
Anonymous, Basic, OAuth, Mutual TLS, AWS Signature, custom. Configured on the Named Credential, not in code. Switching auth mode does not require code changes.
@future(callout=true), Queueable, batch Apex, or Continuation. Pick based on need for state, chaining, or user-facing latency.
- Synchronous callouts cannot fire from a trigger. Wrap in @future(callout=true), Queueable, or platform events.
- Test classes need HttpCalloutMock. Real callouts in tests fail with Methods defined as TestMethod do not support Web service callouts.
- The 120-second aggregate transaction timeout caps total callout time, even if each individual callout finishes within its own timeout.
- Hardcoded endpoints break in sandbox refreshes. Use Named Credentials with environment-specific URLs and refresh-aware metadata.
- Apex callouts require HTTPS in production unless explicitly exempted. HTTP-only endpoints have to be wrapped by a Heroku or middleware proxy.
Trust & references
Cross-checked against the following references.
- Invoking Callouts Using ApexSalesforce Developer Docs
- HTTP (Apex) ClassesSalesforce Developer Docs
Straight from the source - Salesforce's reference material on Callout, Apex.
- Named Credentials OverviewSalesforce Help
- Testing HTTP CalloutsSalesforce Developer Docs
Hands-on resources to go deeper on Callout, Apex.
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Test your knowledge
Q1. What is an Apex Callout?
Q2. What is the maximum duration of a single Apex callout?
Q3. What is the modern recommended way to configure callout endpoints?
Discussion
Loading discussion…