Why ExternalServiceRegistration Bridges OpenAPI, Flow, Agentforce, and Apex
Writing boilerplate HttpRequest builders and JSON.deserialize() wrapper classes in Apex for every third-party REST endpoint is tedious and difficult to govern. ExternalServiceRegistration (externalServiceRegistrations/<Name>.externalServiceRegistration-meta.xml) ingests a standard OpenAPI 2.0 (Swagger) or OpenAPI 3.0 specification and binds it to a NamedCredential.
Once deployed, the platform automatically generates:
- Declarative Invocable Actions available in Flow Builder and Agentforce (GenAiFunction).
- Strongly Typed Dynamic
ExternalService.<ServiceName>Apex Classes for synchronous and asynchronous Apex callouts.
Key Metadata Fields on ExternalServiceRegistration
| Field | Type | Required | Description |
|---|---|---|---|
label |
string |
Yes | Display name of the External Service in Setup. |
namedCredentialReference |
string |
No | (API v57.0+) Developer name of the backing NamedCredential (supersedes legacy namedCredential). |
schemaType |
string |
No | OpenApi or OpenApi3. |
schema |
string |
No | The full OpenAPI 2.0 or 3.0 specification serialized as an XML-escaped JSON or YAML string. |
status |
string |
Yes | complete (validates spec and generates actions/classes) or incomplete. |
operations |
ExternalServiceOperation[] |
No | Lists individual operationId entries from the OpenAPI spec and whether each is active (true/false). |
registrationProviderType |
ExternalServiceRegistrationProviderType |
No | (API v66.0+) Source of the spec: Custom, SchemaInferred (Flow HTTP Callout), Anypoint, MuleSoft, Heroku, ApexRest, AgentToAgent, etc. |
systemVersion |
int |
No | Read-only internal compiler version (9 is current, supporting OpenAPI enums, discriminators, and async Apex callbacks). |
Real-World XML Example (externalServiceRegistrations/StripePaymentService.externalServiceRegistration-meta.xml)
<?xml version="1.0" encoding="UTF-8"?>
<ExternalServiceRegistration xmlns="http://soap.sforce.com/2006/04/metadata">
<description>OpenAPI 3.0 External Service for creating and checking customer payment intents.</description>
<label>StripePaymentService</label>
<namedCredentialReference>Stripe_API_Gateway_NC</namedCredentialReference>
<operations>
<active>true</active>
<name>getPaymentStatus</name>
</operations>
<registrationProviderType>Custom</registrationProviderType>
<schema>{"openapi":"3.0.1","info":{"title":"Payment API","version":"1.0.0"},"paths":{"/v1/payments/{paymentId}":{"get":{"operationId":"getPaymentStatus","parameters":[{"name":"paymentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"amount":{"type":"integer"}}}}}}}}}}}</schema>
<schemaType>OpenApi3</schemaType>
<status>Complete</status>
<systemVersion>9</systemVersion>
</ExternalServiceRegistration>Querying ExternalServiceRegistration via Tooling API
SELECT Id, DeveloperName, MasterLabel, Status, SchemaType,
SystemVersion, RegistrationProviderType, NamedCredentialReference,
LastModifiedDate
FROM ExternalServiceRegistration
ORDER BY DeveloperName ASC(Execute this query against the Tooling API.)
Senior Architect Best Practices & Gotchas
Warning
Include ExternalServiceRegistration When Deploying Flows with HTTP Callouts: Whenever an admin uses the Create HTTP Callout button inside Flow Builder, Salesforce generates both a Flow change and a new ExternalServiceRegistration component. If your CI/CD commit includes only the Flow without its ExternalServiceRegistration and NamedCredential, the Flow deployment will fail with an unresolved invocable action error!
Frequently asked questions
What does deploying an ExternalServiceRegistration automatically generate in Salesforce?
When you deploy an ExternalServiceRegistration with status set to Complete, Salesforce parses the embedded OpenAPI 2.0 or 3.0 JSON/YAML schema and automatically generates invocable Flow actions plus strongly typed ExternalService.ServiceName Apex classes and model objects.
How do Flow HTTP Callout actions relate to ExternalServiceRegistration?
When an admin configures a declarative HTTP Callout action inside Flow Builder, Salesforce automatically creates an ExternalServiceRegistration behind the scenes with registrationProviderType set to SchemaInferred.
Can you call an ExternalServiceRegistration directly from Apex code as well as Flow?
Yes. Every registered operation and schema model is accessible in Apex under the ExternalService namespace (for example, ExternalService.BankService service = new ExternalService.BankService()), supporting both synchronous and asynchronous continuation callouts.
Can you query ExternalServiceRegistration records using the Tooling API?
Yes. Using the Tooling API, you can query ExternalServiceRegistration to inspect DeveloperName, MasterLabel, NamedCredentialId, Status, SystemVersion, RegistrationProviderType, and SchemaType.
Comments
Questions, corrections and tips are welcome. Comments are GitHub Discussions, so you sign in with GitHub.