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.

Use the HTTP Callout action in Flow Builder, point it at a named credential, and let it generate the External Service registration for you. The part that catches people: a record-triggered flow cannot make that callout on its synchronous after-save path, because the record save is uncommitted DML and the platform refuses to call out with pending work. Put the callout on an asynchronous path, or in an autolaunched flow the save invokes later.

Set up the named credential first — the callout config depends on it

Authentication is not part of the flow. It lives in Setup → Named Credentials, and the HTTP Callout configuration screen asks you to pick one before it will let you continue. The Apex Developer Guide’s description applies identically here: “A named credential specifies the URL of a callout endpoint and its required authentication parameters in one definition,” and Salesforce “manages all authentication for Apex callouts that specify a named credential as the callout endpoint so that your code doesn’t have to.”

Two practical consequences. You skip the remote site setting (the named credential covers the host it defines), and when the vendor moves from api.example.com.invalid/v1 to /v2 you edit one record instead of every flow.

You create an external credential holding the authentication protocol and principals, then a named credential that references it and supplies the URL. Permission sets grant users access to the external credential’s principal. If a callout returns 401 for users but works in your own debug run, that permission mapping is where to look — the running user needs the external credential, not just the flow.

The HTTP Callout action writes an External Service for you

In Flow Builder, add an Action element and choose Create HTTP Callout. Name the external service (alphanumerics, no spaces — ConnectToBilling), pick the named credential, then describe one invocation: method, path, query and header parameters, and a sample response body. Flow Builder parses that sample to derive the response structure and generates the registration and supporting Apex classes for you.

What it produces is an ExternalServiceRegistration — a metadata type that stores an OpenAPI 2.0.x or 3.0.x schema as JSON or YAML alongside the named credential reference. Two things follow.

You can go the other direction. If the API publishes an OpenAPI schema, register the External Service directly in Setup → External Services and paste the schema instead of describing one operation at a time. Every operation becomes a separate invocable action available to flows and Apex, with request and response types taken from the schema rather than inferred from one example. For an API with fifteen endpoints that is the only sane route. And because the registration is metadata, a schema diff in a pull request tells you far more than a flow XML diff.

Why the callout fails in a record-triggered flow

This is the error people arrive with:

You have uncommitted work pending. Please commit or rollback before calling out

Nothing is wrong with your endpoint or your credential. An after-save record-triggered flow runs inside the save that fired it. Step 14 of the order of execution, with the record written and not yet committed. The Apex callout documentation states the rule plainly: “You can’t make a callout when there are pending operations in the same transaction,” where pending operations include DML statements, enqueued asynchronous Apex, scheduled Apex, and sent email. The same page confirms the inverse: “You can make callouts before performing these types of operations.”

The save is the pending DML. Your flow does not need a Create Records or Update Records element anywhere in it. The record operation you are reacting to is upstream of everything the flow does. A before-save flow is worse, not better: it runs earlier still, at step 3, and cannot invoke actions at all.

Fix 1: the asynchronous path

On the Start element of a record-triggered flow, under Actions and Related Records, turn on Include a Path to Run Asynchronously. Salesforce describes the intended use as a long-running operation such as a callout to an external web service, and the mechanism is the important bit: the path runs in the background after the original record save is successfully committed. No pending work, so the callout is allowed.

The async path gets its own transaction and the asynchronous limit budget: 200 SOQL queries instead of 100, 60,000 ms of CPU instead of 10,000, 12 MB of heap instead of 6 MB. Here is what you give up, and it is not a footnote:

Property Synchronous path Asynchronous path
Callout allowed No Yes
Record visible before external system knows n/a Yes — always
Failure rolls back the save Yes No
User sees the result on save Yes No
Guaranteed to run within a fixed time Yes No — queued

The last row is the one that bites in production. The async path is queued work. When the org’s async queue is busy it can be seconds or, occasionally, considerably longer. Anything downstream that assumes the external system has already been told is a race condition you have just written into the design.

Fix 2: hand the callout to something else entirely

The async path is the right default. Two alternatives earn their keep. A platform-event-triggered flow (publish an event and call out in the subscriber) buys you replay from the event bus, which the async path cannot offer, at the cost of a second flow and event volume. Invocable Apex with callout=true is the answer when you need retry with backoff, chained calls, or a response body too irregular for a generated schema. You trade the declarative story for real error handling.

Error handling: assume the call fails, because it will

Connect a fault path off the Action element. Without one, an unhandled failure ends the interview, and on the async path there is no user session to show it to. It goes to the flow error email and nowhere else. Three things every callout flow should do:

  • Check the status code, not just the fault path. The HTTP Callout action gives you the response status. A 404 or a 422 is a successful HTTP exchange, so the fault path does not fire. Your flow happily continues with an empty response body unless a Decision element checks the code.
  • Write sync state to the record. A checkbox and a timestamp, or a picklist with Pending, Synced, Failed. Without it you have no way to find the records that never made it, and the async path guarantees there will be some.
  • Cap the retries. A fault path that re-enters the callout is a loop with no exit.

And remember the transaction ceiling: 100 callouts per transaction, a default timeout of 10 seconds per callout, and a maximum cumulative callout timeout of 120 seconds across the whole transaction. A flow looping over a collection with one callout per element hits the cumulative timeout long before it reaches 100 calls if the endpoint is at all slow. Send a batch if the API supports one.

Frequently asked

Can I make a callout from a screen flow?

Yes, and it is the easy case: a user-launched screen flow has no pending DML. Keep the callout ahead of any Create or Update element on the same path, and remember the user is waiting on the endpoint.

Does the HTTP Callout action need a remote site setting?

No. The named credential covers the endpoint’s host, which is one of the stated benefits of using one.

Why does my flow work in debug but fail for users?

Almost always access to the external credential’s principal, not anything in the flow. Grant it by permission set to whoever (or whatever automated process user) actually runs the flow.

Can I edit the generated schema afterwards?

Yes. Retrieve the registration, edit the schema, deploy it back. This is how you fix a response type Flow Builder inferred wrongly from one sample, which happens with nullable fields and empty arrays.

Is the asynchronous path the same as a scheduled path?

No. The async path runs as soon as the platform gets to it after the commit. A scheduled path runs at a defined offset, such as three days before a date field. Callouts belong on the async path.


Reference: Callout Limits and Limitations and Named Credentials as Callout Endpoints, Salesforce Apex Developer Guide; ExternalServiceRegistration, Metadata API Developer Guide; Triggers and Order of Execution. Asynchronous path behaviour per “Connect a Record-Triggered Flow to an External System Using an Asynchronous Path” and “Connecting to an API Without a Connector Using HTTP Callout”, Salesforce Help.