Blog

Going Headless with Agentforce

Salesforce's recently announced Headless 360 strategy describes multi-agent deployment topologies in which Agentforce can both call external agents and answer calls from them. For multi-app agentic workflows, that access provides real operational leverage. An Agentforce agent's topics, actions, and Knowledge grounding encode how a business actually handles complex work, and the Agent API makes that agent available to a Prompt One workflow as an autonomous tool it can use: the workflow starts a session server-side, delegates the CRM work, and folds the answers into the larger motion. Each platform's agents become more powerful because the other's are in reach.

AI tooling changes fast and keeping up is a job in itself, and Agentforce is no different. Our initial design explorations used classic Connected Apps. Since then we've learned that Salesforce not only moved the Agent API to External Client Apps (ECAs) but has deprecated Connected Apps entirely. Consider what follows a public service announcement for anyone wiring an external agent into Agentforce directly. If you're a Prompt One user, this is not required reading; the platform handles all of it.

Design exploration: Connected Apps

Our first working integration followed the Agent API documentation of the time: a classic Connected App with the client-credentials flow, the Api, Chatbot, and SFAP scopes, and a run-as integration user. Mint a token, POST to /einstein/ai-agent/v1/agents/{agentId}/sessions, and the agent answers.

The platform moved

Salesforce is retiring Connected Apps in favor of ECAs, which split an app's global OAuth definition cleanly from its org-local policies. The retirement arrived in stages rather than all at once: creating a new Connected App was disabled by default for new orgs in Summer '25, that restriction reached every org in Spring '26, and with the Summer '26 release the ECA is the standard for new integrations. Existing Connected Apps continue to work and can be migrated, but anything new has to be built on an ECA. The documentation caught up with a noticeable lag: through mid-2025 the Agent API docs listed Connected Apps as the only supported app type, even as the platform began phasing them out. Current documentation requires an ECA, and new integrations should be built on one.

We migrated, and immediately hit two blocking issues the troubleshooting docs do not cover.

Blocker one: the connection dialog cannot see your ECA

Instinct and history say to wire the new ECA to the agent, and the agent's Connections tab suggests that's possible through its "Add external app" dialog. But its picker is a Connected App lookup. For new agents, this dropdown will always be empty and won't show the ECA you built for this purpose. This is not a misconfiguration. The dialog predates ECAs but has not yet been updated for the ECA model.

Blocker two: the empty 404

Separately, a second confusing behavior emerges. The token mints, which proves the org knows your ECA: the key and secret are valid, the client-credentials flow is on, the run-as user resolves. Seems like it all should work. Unfortunately, the Agent API enforces additional requirements the token endpoint does not check, so every session request returns a 404 with an empty body.

The official troubleshooting page attributes 404s to a wrong token or endpoint. We found we had neither, yet the 404s kept coming. We worked through seven misconfigurations of the agent and the ECA, and every one produced the identical empty 404. The response never revealed which setting was at fault.

Intuitively, the two blockers seemed linked: the unconnected app explained the 404s. We just needed to connect the app. That turned out to be wrong.

There is no connection step

The Agent API never binds an ECA to an agent. Each request already carries both identifiers: the access token identifies the calling ECA, and the {agentId} in the URL selects the agent. A correctly configured ECA can call any API-supported agent in the org. The get-started guide never asks for a binding, and the dialog is a vestige of the earlier Connected App model.

Adding to the confusion is that the ECA does show up in the Connections panel, but under an External Apps list, without you clicking anything. That is not a connection; it is a mirror of the ECA's own configuration: the list shows every app in the org whose settings qualify it for the Agent API.

Left: the Add external app dialog, whose Connected App picker cannot see an ECA. Right: the External Apps list, where the ECA appears on its own

We verified this: a fully configured ECA appeared in the list on its own; an ECA stripped to bare OAuth did not. To understand this, it helps to split the settings the Agent API checks into two categories, visibility and functionality, each governing a separate behavior:

  • Visibility controls whether the ECA appears in the External Apps list: all four Agent API scopes (Api, RefreshToken, Chatbot, SFApiPlatform) plus named-user JWT enabled. Drop any one and the ECA vanishes from the list.
  • Functionality controls whether it can mint tokens and run sessions: the client-credentials flow enabled, with a run-as user on the OAuth policy. These settings have no effect on the list: an ECA can sit in External Apps and still fail every token request.

The configuration that actually works

On the agent side, three conditions must hold; each failure is the same empty 404:

  • A supported type. The preloaded employee agent is an internal copilot and does not answer the API; use an Agentforce Service Agent.
  • Active, not Draft.
  • At least one Topic with actions defined.

On the ECA side, each setting tagged with its configuration category:

  • All four scopes (Api, RefreshToken, Chatbot, SFApiPlatform) (visibility). RefreshToken is required even though the client-credentials flow never issues one; it is an Einstein Bots prerequisite.
  • Named-user JWT enabled on the global OAuth settings (visibility). The most commonly missed flag: the Bots runtime validates JWT-form tokens, and without it every session call falls through to the empty 404.
  • Client Credentials Flow enabled (functionality). Without it the token mint fails with unsupported_grant_type, while the ECA still shows in the list.
  • A run-as user on the OAuth policy, with admin-approved pre-authorized users (functionality). This is the identity sessions execute as; the auto-generated Einstein Agent User profile grants are not what makes the ECA eligible.
  • PKCE required and consumer secret optional round out our working configuration.

One note from both eras: the consumer secret is capturable only through the Setup UI (Manage Consumer Details, verified by emailed code). A consumerSecret supplied in ECA metadata is silently ignored. Plan on the manual hop at every rotation.

What this means for Prompt One users

The Agent API turns an Agentforce agent into a service the rest of an enterprise's automation can call, exactly what third-party platforms need. The irony is that a Prompt One user never needs to know any of these idiosyncratic implementation details. Prompt One is self-serve and built for business users; anyone, not just a Salesforce developer, can add Agentforce capabilities to a workflow simply by asking for them. Prompt One takes care of everything. Agentforce support arrives in an upcoming release.

If you're exploring how Agentforce fits alongside the other ways to build an enterprise agent, that is the subject of our framework whitepaper, Choosing an Enterprise Agent Architecture: a four-step decision framework covering the five architectures deployed in enterprises today. You can read it in full here, or download the PDF. If you want to learn more about how Prompt One delivers compiled workflow agents, the companion whitepaper Enterprise Agents, Compiled covers the architecture as we've implemented it. And if you'd rather see the platform itself, try it now.

← All posts