AD SPACE AVAILABLE · BRAND PARTNERS WELCOME

Building and Exposing Custom Invocable Apex, Flows, and MuleSoft APIs as Agentforce Actions

365Finds Editorial
Indexed 11,430 Wiki articles

Put 365 Wiki to work with your AI

Copy the prompt below, paste it into the AI you already use, then ask your question.

Download full Skill

Try it with the prompt first. If you use 365 Wiki often, install the full 365Wiki Skill so you do not have to paste it again. No regular AI? Gemini or Microsoft Copilot on the web will work.

365Wiki Skill

Salesforce Agentforce transforms enterprise AI from passive conversational chat into autonomous agency. Instead of simply generating answers based on retrieved text, an autonomous agent assesses customer intent, selects specialized enterprise tools, executes real-time transactions, and observes the results to determine the next operational step.

Out-of-the-box standard actions provide basic CRM capabilities such as drafting emails or summarizing records. However, enterprise implementations inevitably require proprietary business rules, multi-step orchestration across legacy systems, and real-time external data access. Developers and enterprise architects must extend Agentforce by building Custom Actions backed by three foundational pillars:

  1. Invocable Apex Methods: Deterministic, programmatic logic handling complex computations, custom validations, and secure data access.
  2. Headless Autolaunched Flows: Low-code declarative automations executing business workflows and standard database transactions without manual coding.
  3. MuleSoft APIs via External Services and API Catalog: Enterprise integrations bridging core ERPs, payment processors, and distributed microservices directly into the agent's runtime.

This guide details the end-to-end architecture, technical implementation steps, context engineering best practices, and security governance required to build and expose these three action types in Agentforce.


1. Core Architecture: How Agentforce Understands and Executes Actions

To build reliable custom actions, developers must understand the reasoning engine powering Agentforce: the Atlas Reasoning Engine.

[ User Interaction / Omni-Channel / Digital Channel ]
                        │
                        ▼
          [ Atlas Reasoning Engine ]
         (ReAct: Reason - Act - Observe)
                        │
       ┌────────────────┼────────────────┐
       ▼                ▼                ▼
[ Topic Classification ] │ [ Grounding & Context Filter ]
       │                │
       └───────┬────────┘
               ▼
     [ Tool / Action Selection ]
               │
   ┌───────────┼───────────┐
   ▼           ▼           ▼
[ Apex ]   [ Flow ]   [ MuleSoft / API ]
   │           │           │
   └───────────┼───────────┘
               ▼
[ Execution Output Observed by Atlas ]
               │
               ▼
[ Final Response or Subsequent Action ]

The ReAct Pattern and Context Engineering

The Atlas Reasoning Engine operates on a Reason-Act-Observe (ReAct) loop. When an end user asks a question or triggers an event:

In traditional programmatic development, code communicates through strict types and explicit method calls. In Agentforce, metadata is the prompt. The engine does not inspect method internals; it reads the action's label, description, input parameter annotations, and action instructions. Ambiguous descriptions cause tool confusion and hallucinations, whereas precise descriptions produce deterministic execution.


2. Exposing Invocable Apex as Custom Actions

Apex actions provide the backbone for complex, high-performance logic that requires programmatic flexibility, bulk database operations, or intricate data structures.

Step 1: Design the Invocable Apex Class

Agentforce actions rely on the @InvocableMethod annotation. The method must be public or global, static, and accept a List of input wrapper objects while returning a List of output wrapper objects.

Here is a production-grade pattern for an order cancellation action:

public with sharing class OrderCancellationService {

    // Input Wrapper defining parameters required by the Agent
    public class OrderCancellationRequest {
        @InvocableVariable(
            label = 'Order Number' 
            description = 'The unique alphanumeric identifier of the order to cancel, e.g., ORD-10023.' 
            required = true
        )
        public String orderNumber;

        @InvocableVariable(
            label = 'Cancellation Reason' 
            description = 'The customer-provided explanation for the cancellation request.' 
            required = false
        )
        public String reason;
    }

    // Output Wrapper returning structured data back to the Atlas Reasoning Engine
    public class OrderCancellationResult {
        @InvocableVariable(
            label = 'Is Success' 
            description = 'Boolean flag indicating whether the order was successfully marked as cancelled.'
        )
        public Boolean isSuccess;

        @InvocableVariable(
            label = 'Cancellation Reference Code' 
            description = 'Audit tracking number generated for the confirmed cancellation.'
        )
        public String referenceCode;

        @InvocableVariable(
            label = 'Status Message' 
            description = 'Human-readable explanation of the operation outcome or specific failure reason.'
        )
        public String message;
    }

    @InvocableMethod(
        label = 'Cancel Customer Order'
        description = 'Cancels a pending customer order and issues a cancellation audit code. Use this action only when the order status is Pending or Processing and the customer explicitly requests cancellation.'
        category = 'Order Management'
    )
    public static List<OrderCancellationResult> cancelOrders(List<OrderCancellationRequest> requests) {
        List<OrderCancellationResult> results = new List<OrderCancellationResult>();

        for (OrderCancellationRequest req : requests) {
            OrderCancellationResult res = new OrderCancellationResult();
            
            try {
                // Enforce User Mode security checks
                List<Order> orders = [
                    SELECT Id, Status, TotalAmount 
                    FROM Order 
                    WHERE OrderNumber = :req.orderNumber 
                    WITH USER_MODE 
                    LIMIT 1
                ];

                if (orders.isEmpty()) {
                    res.isSuccess = false;
                    res.message = 'No active order found with number: ' + req.orderNumber;
                    results.add(res);
                    continue;
                }

                Order targetOrder = orders[0];
                if (targetOrder.Status == 'Activated' || targetOrder.Status == 'Completed') {
                    res.isSuccess = false;
                    res.message = 'Order ' + req.orderNumber + ' is already finalized and cannot be cancelled automatically.';
                    results.add(res);
                    continue;
                }

                targetOrder.Status = 'Cancelled';
                targetOrder.Description = 'Cancelled via Agentforce. Reason: ' + (req.reason != null ? req.reason : 'Unspecified');

                Database.SaveResult sr = Database.update(targetOrder, AccessLevel.USER_MODE);
                if (sr.isSuccess()) {
                    res.isSuccess = true;
                    res.referenceCode = 'CAN-' + System.currentTimeMillis();
                    res.message = 'Order successfully cancelled.';
                } else {
                    res.isSuccess = false;
                    res.message = 'Failed to update order database record.';
                }
            } catch (Exception ex) {
                res.isSuccess = false;
                res.message = 'Internal error during order cancellation: ' + ex.getMessage();
            }

            results.add(res);
        }

        return results;
    }
}

Critical Apex Best Practices for Agentforce

Step 2: Register the Apex Method as an Agent Action

  1. From Salesforce Setup, type Agent in Quick Find and select Agentforce Assets (or Agent Actions).
  2. Click New Agent Action.
  3. Choose Reference Action Type as Apex.
  4. Select OrderCancellationService and the Cancel Customer Order method.
  5. Review the auto-populated Label, API Name, and Descriptions derived from your @InvocableMethod annotations.
  6. Refine the Action Instructions: Specify conditions under which the agent should invoke this action (for example: "Trigger this action when a verified customer explicitly asks to cancel an existing order. Prompt for the Order Number if not provided.").
  7. Save the action.

3. Exposing Headless Flows as Custom Actions

Autolaunched Flows enable administrators and developers to deliver low-code transactional actions quickly, leveraging Flow Builder's declarative CRUD logic, record routing, and approval capabilities.

Flow Type Constraint

Agentforce can invoke only Autolaunched Flow (No Trigger). Screen Flows require interactive human UI rendering, and Record-Triggered Flows fire on asynchronous or synchronous database events. A headless flow provides a clean request-response contract that fits the ReAct execution model.

[ User Prompt: "Update my shipping address to 742 Evergreen Terr" ]
                           │
                           ▼
          [ Agentforce: Action Planner ]
                           │
    (Maps extracted parameters: orderId, street, city)
                           │
                           ▼
     [ Autolaunched Flow: Update Shipping Address ]
             ┌─────────────────────────┐
             │ Get Record: Target Order│
             ├─────────────────────────┤
             │ Assignment: New Address │
             ├─────────────────────────┤
             │ Update Record: Order    │
             └─────────────────────────┘
                           │
    (Returns outputs: isUpdated = True, confirmationMsg)
                           │
                           ▼
          [ Atlas Engine Formulates Reply ]

Step-by-Step Flow Configuration

  1. Create the Flow: Open Flow Builder and select Autolaunched Flow (No Trigger).
  2. Define Input Variables:
    • Create a text resource variable named var_orderId.
    • Check Available for input.
    • Fill in the Description: "The 18-character Salesforce Record ID of the target Order record."
    • Create variables for payload inputs (e.g., var_streetAddress, var_postalCode) with descriptive text.
  3. Define Output Variables:
    • Create a boolean resource variable var_isUpdated. Check Available for output. Description: "True if the address update was successfully committed."
    • Create a text resource variable var_statusMessage. Check Available for output.
  4. Implement Declarative Logic:
    • Use a Get Records element to find the active order.
    • Use a Decision element to check if the order has already shipped.
    • If allowed, use an Update Records element to persist the new address.
    • Use an Assignment element to set var_isUpdated = True and populate var_statusMessage.
  5. Save and Activate: Save the flow as Agent_Update_Order_Address and activate it.

Step 3: Register the Flow Action

  1. Navigate to Setup > Agentforce Assets > New Agent Action.
  2. Select Reference Action Type = Flow.
  3. Select Agent_Update_Order_Address.
  4. The system inspects variables marked Available for input and Available for output. Verify that each variable's description provides clear guidance for the LLM.
  5. Set Action Instructions and execution policies. For record mutation, evaluate whether to enable Require Confirmation so the user confirms changes before execution.

4. Exposing MuleSoft APIs via External Services and API Catalog

Enterprise agents frequently need data outside Salesforce—such as inventory residing in SAP, billing history in Stripe, or shipping milestones in FedEx. MuleSoft serves as the integration backbone, while Salesforce exposes those APIs as callable agent actions using External Services and the Salesforce API Catalog.

Architectural Pathways

Developers have two primary methods to bring MuleSoft APIs into Agentforce:

Integration PathMechanismBest Suited For
MuleSoft for Agentforce: Topic Center & API CatalogNative synchronization from Anypoint Exchange into Salesforce API CatalogOrganizations with managed Anypoint Platform governance, central API teams, and OpenAPI/RAML specs.
External Services for MuleSoftDirect registration via Named Credentials and OpenAPI 3.0/2.0 specificationsPoint-to-point integration or specific system APIs needing fast low-code invocation in Flow and Agentforce.
[ Backend ERP / SAP / Core Banking ]
                  │
                  ▼
   [ MuleSoft Anypoint Platform ]
 (System, Process, Experience APIs)
                  │
   (Topic Center / OAS 3.0 Specs)
                  │
                  ▼
  [ Salesforce Anypoint Setup / Sync ]
                  │
     ┌────────────┴────────────┐
     ▼                         ▼
[ Named Credentials ]  [ Salesforce API Catalog ]
     │                         │
     └────────────┬────────────┘
                  ▼
      [ External Services ]
 (Generates Invocable Actions)
                  │
                  ▼
  [ Agentforce Custom Action Library ]

Step 1: Design Clean OpenAPI Specifications (OAS)

The Atlas Reasoning Engine inspects the OpenAPI schema to identify path parameters, request bodies, and expected responses. APIs built for agents require strict schema governance:

Example OpenAPI 3.0 specification snippet for an ERP Inventory Lookup:

openapi: 3.0.3
info:
  title: Enterprise Warehouse API
  version: 1.0.0
  description: Real-time warehouse inventory and shipping availability service.
paths:
  /inventory/{sku}:
    get:
      summary: Retrieve warehouse inventory levels by SKU
      description: Returns available stock count, warehouse location, and replenishment lead times for a given product SKU.
      operationId: getInventoryBySku
      parameters:
        - name: sku
          in: path
          required: true
          description: The alphanumeric manufacturer SKU code, e.g., PROD-WIDGET-99.
          schema:
            type: string
      responses:
        '200':
          description: Successful stock level inquiry
          content:
            application/json:
              schema:
                type: object
                properties:
                  sku:
                    type: string
                    description: The requested product SKU.
                  quantityOnHand:
                    type: integer
                    description: Physical units available in warehouse.
                  isAvailableToShip:
                    type: boolean
                    description: Indicates whether immediate fulfillment is possible.
                  warehouseRegion:
                    type: string
                    description: Primary fulfillment hub handling the SKU.
        '404':
          description: SKU not found in inventory catalog

Step 2: Sync and Expose the API in Salesforce

  1. Configure Anypoint Platform Connection: In Salesforce Setup, search for Anypoint Platform Setup. Authorize your Salesforce org using your Anypoint Organization ID and client credentials.
  2. Catalog Synchronization:
    • In MuleSoft Topic Center or Anypoint Exchange, tag the target API specification with sf-api-catalog.
    • In Salesforce Setup, open the API Catalog. Locate the synchronized MuleSoft API.
    • Click Activate Operations as Actions.
  3. Configure Named Credentials: Ensure a secure Named Credential (using OAuth 2.0 or External Client Credentials) is assigned to the service to authenticate HTTP callouts securely.
  4. Create Agent Action from External Service:
    • Navigate to Agentforce Assets > New Agent Action.
    • Choose Reference Action Type = External Service.
    • Select the registered warehouse service and the getInventoryBySku operation.
    • Review and fine-tune parameter descriptions.

5. Wiring Actions into Agentforce Builder (The Topic Layer)

Custom actions do not float independently in the agent runtime. To make an action callable, it must be assigned to an Agent Topic within Agentforce Builder.

[ Autonomous Agent: Customer Service Agent ]
                       │
       ┌───────────────┴───────────────┐
       ▼                               ▼
[ Topic: Order Inquiries ]   [ Topic: Technical Support ]
 (Classification & Scope)     (Classification & Scope)
       │
   ┌───┴───────────────────────────────┐
   ▼                                   ▼
[ Action: Check Order Status ]  [ Action: Cancel Customer Order ]
 (Autolaunched Flow)             (Invocable Apex)

Topic Assignment and Scoping

  1. Open Agentforce Builder from Setup.
  2. Select your target agent (e.g., Service Agent or Sales Agent) and enter edit mode.
  3. Select an existing Topic or click New Topic (e.g., Order Logistics and Changes).
  4. Define the Topic Classification Description: Explain clearly what user questions fall under this topic.
  5. In the Topic's Actions panel, click Add Action and pick your newly created Custom Actions (Apex, Flow, MuleSoft).

Authoring Topic and Action Instructions

The instructions guide the agent's decision-making process:

### Topic Instructions: Order Logistics and Changes
- Help the user with order tracking, status inquiries, address updates, and cancellations.
- Never cancel an order without first asking the user to confirm their intention.
- When an order cancellation fails due to finalized status, explain that the package has already shipped and offer the return policy.

### Action Instructions: Cancel Customer Order
- Only execute this action after the user explicitly provides the Order Number and agrees to the cancellation prompt.
- If the Order Number is missing, ask the user: "Could you please provide the order number you would like to cancel?"
- Once executed, communicate the Cancellation Reference Code back to the customer.

Execution Policies and Human-in-the-Loop Safeguards

For state-modifying actions (DML inserts/updates, payments, cancellations), toggle Require Confirmation in the action settings. This forces Agentforce to generate a conversational confirmation prompt (e.g., "Are you sure you want to cancel order ORD-10023? This cannot be undone.") before invoking the underlying Apex, Flow, or API callout.


6. Architecture Comparison and Selection Matrix

Choosing the right technology for custom actions ensures long-term maintainability, security, and low operational latency.

Architectural DimensionInvocable ApexAutolaunched FlowMuleSoft External Services
Primary SkillsetSalesforce Developer (Apex)Salesforce Admin / Low-Code DevIntegration Architect / MuleSoft Dev
Execution DomainNative Salesforce CoreNative Salesforce CoreExternal Enterprise Systems
Ideal Use CasesComplex math, multi-object querying, custom security rules, programmatic transformationsStandard CRM CRUD, record routing, approvals, existing declarative automationsERP sync (SAP, Oracle), payment gateways, external warehouses, cross-cloud microservices
Governor Limits & LatencyStandard Apex CPU (10s synchronous), SOQL/DML limitsSubject to Flow iteration and element execution limitsExternal API latency, callout timeout limits (up to 120s), rate limiting
Maintenance ModelSource code managed via Git, SFDX, and metadata packagingDeclarative versioning in Flow BuilderAPI contracts governed in Anypoint Exchange and API Governance
Error HandlingProgrammatic try-catch with custom wrapper classesFault connectors and declarative branch assignmentStandard HTTP status codes (2xx, 4xx, 5xx) with JSON error payloads

7. Testing, Security, and Production Deployment

1. Agent User Permissions and Security Context

Custom actions execute under the context of the configured Agent User. A common failure during rollout occurs when the agent identifies the correct action but encounters runtime execution failures due to missing object permissions.

2. Multi-Tier Testing Strategy

  1. Unit Testing: Standard Apex unit tests (with 85%+ code coverage) ensuring bulk safety, null handling, and User Mode access.
  2. Interactive Live Testing in Agent Builder: Use the conversation preview pane to trace the agent's thought process. Inspect the reasoning tab to verify that Atlas correctly classifies the topic, extracts parameters, and receives structured outputs.
  3. Agentforce Testing Center: Run bulk test suites against hundreds of representative customer utterances. Define custom evaluation criteria to evaluate tool selection accuracy, hallucination rates, and parameter mapping precision across version releases.

By combining the programmatic precision of Invocable Apex, the declarative speed of Autolaunched Flows, and the enterprise connectivity of MuleSoft APIs, developers create an extensible, secure foundation for autonomous AI operations on the Salesforce Platform.


References