Call LLMs from Apex with the Models API

No connected app, no API key management, trust layer built in — generative AI as a plain Apex call. A hands-on AI Projects Lab build.

The scenario

Falcon Retail's sales team wants a one-paragraph "account brief" — recent activity, open deals, risks — on every account page before a call. Prompt Builder could do it, but the team also wants the same summary reused in a nightly digest email and an agent action. So we build it once, in Apex, with the Models API.

For beginners: the Models API is Salesforce's gateway to LLMs (OpenAI, Anthropic, Gemini models and more) with the Einstein Trust Layer in the path: data masking, toxicity scoring, audit trail, zero retention agreements. From Apex you call it via the aiplatform namespace — no endpoints, secrets or callout config.

The summarizer class

public with sharing class AccountBriefService {

    // Reusable: callable from LWC (via @AuraEnabled wrapper),
    // Flow, a nightly batch, or an Agentforce action.
    public static String generateBrief(Id accountId) {
        // 1. Gather grounding data with security enforced
        Account acc = [SELECT Name, Industry, AnnualRevenue,
                              (SELECT Subject, ActivityDate FROM Tasks
                               WHERE ActivityDate = LAST_N_DAYS:90
                               ORDER BY ActivityDate DESC LIMIT 10),
                              (SELECT Name, StageName, Amount, CloseDate
                               FROM Opportunities WHERE IsClosed = false)
                       FROM Account WHERE Id = :accountId
                       WITH USER_MODE];

        String context = JSON.serializePretty(acc);

        // 2. Build the request against a supported model
        aiplatform.ModelsAPI.createGenerations_Request request =
            new aiplatform.ModelsAPI.createGenerations_Request();
        request.modelName = 'sfdc_ai__DefaultOpenAIGPT4OmniMini';

        aiplatform.ModelsAPI_GenerationRequest body =
            new aiplatform.ModelsAPI_GenerationRequest();
        body.prompt =
            'You are a sales assistant. Using ONLY the JSON below, ' +
            'write a 4-sentence account brief: current relationship, ' +
            'open pipeline, recent activity, one suggested talking point. ' +
            'If data is missing, say so rather than inventing it.\n\n' + context;
        request.body = body;

        // 3. Call through the Einstein Trust Layer
        aiplatform.ModelsAPI modelsAPI = new aiplatform.ModelsAPI();
        aiplatform.ModelsAPI.createGenerations_Response res =
            modelsAPI.createGenerations(request);

        return res.Code200.generation.generatedText;
    }
}
Requirements: Einstein Generative AI enabled in the org and the Models API add-on/permissions; test in a Developer Edition org with Agentforce first. LLM calls are metered — cache results (e.g. store the brief with a timestamp) instead of regenerating on every page view.

Reusing it three ways

  1. Record page: a small LWC with a "Generate brief" button calling an @AuraEnabled wrapper.
  2. Nightly digest: a Batchable that generates briefs for accounts with meetings tomorrow and emails owners.
  3. Agent action: wrap it in an @InvocableMethod and your Agentforce sales agent can answer "brief me on Acme before my 3pm."

One service class, three surfaces — that's the payoff of doing it in Apex instead of clicks.

Sources: Access Models API with Apex — official guide · Supported Models