ai-model-integration-apex

Use when calling AI models from Apex code — including the aiplatform.ModelsAPI External Services wrapper, Einstein Platform Services (Vision and Language), response parsing, token lifecycle management, and caching strategies. Trigger keywords: aiplatform.ModelsAPI, createGenerations, createChatGenerations, createEmbeddings, Einstein Platform Services, Einstein Vision, Einstein Language, ModelsAPI callout, AI callout from Apex. NOT for Agentforce actions, Einstein Next Best Action, or Prompt Builder flows.

Best use case

ai-model-integration-apex is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when calling AI models from Apex code — including the aiplatform.ModelsAPI External Services wrapper, Einstein Platform Services (Vision and Language), response parsing, token lifecycle management, and caching strategies. Trigger keywords: aiplatform.ModelsAPI, createGenerations, createChatGenerations, createEmbeddings, Einstein Platform Services, Einstein Vision, Einstein Language, ModelsAPI callout, AI callout from Apex. NOT for Agentforce actions, Einstein Next Best Action, or Prompt Builder flows.

Teams using ai-model-integration-apex should expect a more consistent output, faster repeated execution, less prompt rewriting, better workflow continuity with your supporting tools.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.
  • You already have the supporting tools or dependencies needed by this skill.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/ai-model-integration-apex/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/apex/ai-model-integration-apex/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/ai-model-integration-apex/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How ai-model-integration-apex Compares

Feature / Agentai-model-integration-apexStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when calling AI models from Apex code — including the aiplatform.ModelsAPI External Services wrapper, Einstein Platform Services (Vision and Language), response parsing, token lifecycle management, and caching strategies. Trigger keywords: aiplatform.ModelsAPI, createGenerations, createChatGenerations, createEmbeddings, Einstein Platform Services, Einstein Vision, Einstein Language, ModelsAPI callout, AI callout from Apex. NOT for Agentforce actions, Einstein Next Best Action, or Prompt Builder flows.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# AI Model Integration Apex

This skill activates when Apex code needs to call an AI model — either through the `aiplatform.ModelsAPI` External Services wrapper (the modern path) or through legacy Einstein Platform Services that use an OAuth 2.0 JWT bearer token. The skill covers correct API usage, response parsing, token lifecycle management via Platform Cache, and asynchronous Queueable patterns for bulk AI workloads.

---

## Before Starting

Gather this context before working on anything in this domain:

- Which API surface is in use: `aiplatform.ModelsAPI` (modern, External Services-generated), legacy Einstein Vision/Language (REST with JWT), or a direct HTTP callout to an external LLM endpoint?
- What is the transaction volume — single-record synchronous, trigger-driven bulk, or scheduled batch?
- Does a Platform Cache partition exist in the org? What is the configured TTL?
- What are the org's Einstein Request entitlement limits, and what callout-per-transaction budget remains?
- Will this run inside a trigger, a Flow-invoked action, a Queueable, or a Batch class? Each context has different callout limits and restrictions.

---

## Core Concepts

### aiplatform.ModelsAPI — The Modern Apex Path

The `aiplatform.ModelsAPI` class is autogenerated by the External Services framework and provides three primary methods:

- `createGenerations(modelApiName, request)` — for text generation (completion style)
- `createChatGenerations(modelApiName, request)` — for chat-style prompts with message history
- `createEmbeddings(modelApiName, request)` — for generating vector embeddings

The model API name is a string such as `sfdc_ai__DefaultOpenAIGPT4OmniMini`. Responses are typed objects; generated text surfaces at `response.Code200.generation.generatedText` for completion calls and at `response.Code200.generations[0].message.content` for chat calls.

Although the External Services wrapper hides the underlying authentication exchange, every call still counts against the org's Einstein Request entitlement budget and against the standard Apex callout governor limit (100 callouts per transaction, 120-second per-callout timeout). The wrapper does not provide retry or throttling logic — that responsibility belongs to the calling Apex.

### Legacy Einstein Platform Services — JWT Token Lifecycle

Legacy Einstein Vision and Language services authenticate with an OAuth 2.0 JWT bearer token obtained from `https://api.einstein.ai/v2/oauth2/token`. This token is a short-lived credential that must be included as a Bearer token on every REST callout.

The critical behavior: **the token does not auto-refresh**. Once obtained, it is valid for a limited window. If Apex fetches a new token on every transaction rather than reusing a cached token, each transaction burns a separate callout and makes a redundant authentication call. Under moderate load this doubles callout usage per transaction and can exhaust per-hour Einstein Request entitlements far faster than the model calls alone would.

The correct pattern is to store the token in Platform Cache (`Cache.Org`) with a TTL slightly below the token's validity window, check the cache before every callout, and only request a new token on a cache miss.

### Governor Limits and Bulk AI Processing

Apex enforces 100 callouts per transaction. A trigger processing 50 records that each require one AI model call would hit the limit at 50 records in a single transaction. Bulk AI workloads must be moved asynchronous. The correct structure is a Queueable chain: each Queueable job processes a bounded subset of records, makes its AI callout(s), persists results, and re-enqueues itself for the next batch if records remain. This pattern keeps every execution within callout limits and respects the 60-second Queueable timeout for callout-capable jobs.

Batch Apex can also make callouts, but only from `execute()` and only when the batch is defined with `Database.AllowsCallouts`. The batch scope (records per execute call) must be sized so the number of AI callouts per execute stays within the 100-callout limit.

### Response Parsing

Both `aiplatform.ModelsAPI` and legacy Einstein REST APIs return typed responses. Do not use dynamic JSON deserialization (`JSON.deserializeUntyped`) for ModelsAPI calls — the generated types provide compile-time safety. Null-check intermediate objects before traversing nested paths; a model returning a non-200 status code will populate a different response path and leave `Code200` null.

---

## Common Patterns

### Cache-Aside Token Management for Legacy Einstein Services

**When to use:** Any Apex class making legacy Einstein Vision or Language callouts.

**How it works:** Before constructing the HTTP request, check `Cache.Org.get(cacheKey)`. On a hit, use the cached token string directly. On a miss or null, call the JWT token endpoint, store the result in `Cache.Org.put(cacheKey, token, ttlSeconds)` with a TTL that is 30–60 seconds shorter than the actual token expiry, and proceed.

**Why not the alternative:** Fetching a fresh token per transaction doubles callout consumption and risks hitting per-hour Einstein Request limits before the model calls exhaust them.

### Queueable Chain for Bulk AI Processing

**When to use:** Triggers, batch jobs, or any context that passes more records to AI processing than can be handled in a single synchronous transaction.

**How it works:** The trigger or entry point collects record IDs and enqueues the first Queueable. Each Queueable processes a fixed slice (e.g. 5–10 records per execution), makes the AI callout(s), updates results, and calls `System.enqueueJob(new AiProcessQueueable(remainingIds))` if the list is not exhausted.

**Why not the alternative:** Synchronous processing in a trigger exceeds the callout limit at scale and can produce partial failures that leave records in inconsistent state.

### aiplatform.ModelsAPI Chat Generation with Null-Safe Response Parsing

**When to use:** Any call to a chat-capable model (e.g. GPT-4o Mini) where the response should be extracted safely.

**How it works:** Call `createChatGenerations`, check `response.Code200 != null`, then read from the typed path. Wrap in a try-catch for `aiplatform.ModelsAPI.createChatGenerationsException` to handle API-level errors distinctly from Apex exceptions.

---

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Single-record synchronous AI call | aiplatform.ModelsAPI with null-safe response parsing | Clean typing, no auth complexity |
| Bulk records needing AI processing | Queueable chain with bounded slice per execution | Stay within 100-callout and timeout limits |
| Legacy Einstein Vision or Language | JWT token via Platform Cache (cache-aside) | Avoid redundant token callouts under load |
| Token or response value reuse across short time window | Cache.Org with explicit TTL and fallback | Reduce entitlement burn and callout count |
| Response status is unexpected | Check Code200 null, handle alternate status codes | ModelsAPI routes failures to different typed paths |

---

## Recommended Workflow

Step-by-step instructions for an AI agent or practitioner activating this skill:

1. Identify the API surface — confirm whether the project uses `aiplatform.ModelsAPI`, legacy Einstein REST (Vision/Language), or direct HTTP to an external model. Each path has different auth requirements and response shapes.
2. Check entitlement and callout budget — confirm Einstein Request limits and how many callouts the target transaction context can safely make. Determine if async processing is required.
3. Implement the API call — use the typed ModelsAPI methods (`createGenerations`, `createChatGenerations`, or `createEmbeddings`) with the correct model API name string. For legacy Einstein services, implement the cache-aside token pattern against Platform Cache before writing the HTTP callout.
4. Add null-safe response parsing — traverse the typed response path only after a null-check on `Code200`. Add a try-catch for API-specific exception types and log meaningful error context.
5. Design for scale — if transaction volume can exceed safe callout budget, refactor to a Queueable chain. Size each job's slice so total callouts per execution stay below 100.
6. Validate — run the checker script, confirm Platform Cache TTL is set below token expiry, confirm Queueable chain terminates correctly on empty input, and confirm no synchronous bulk callout patterns remain.

---

## Review Checklist

- [ ] aiplatform.ModelsAPI model API name string is correct and matches an available model in the org.
- [ ] Response traversal null-checks `Code200` before reading nested fields.
- [ ] Legacy Einstein JWT token is stored in Platform Cache with TTL below actual token expiry.
- [ ] Synchronous callout paths stay within 100-callout limit per transaction.
- [ ] Bulk AI processing uses Queueable chain or batch with AllowsCallouts, not synchronous trigger logic.
- [ ] Error handling distinguishes model API errors (non-200 responses) from network or Apex exceptions.
- [ ] Einstein Request entitlement impact has been estimated for expected volume.

---

## Salesforce-Specific Gotchas

1. **aiplatform.ModelsAPI is not authentication-free despite appearances** — the External Services wrapper handles the token exchange internally, but every call still consumes an Einstein Request entitlement credit. High-frequency use without caching intermediate results will exhaust entitlements before callout limits are hit.
2. **Legacy Einstein JWT tokens do not auto-refresh** — Apex must track token lifecycle explicitly. Without Platform Cache, every transaction fetches a fresh token, doubling callout count and burning per-hour entitlements twice as fast.
3. **Callout limit of 100 per transaction is hard** — a trigger processing a full batch of 200 records that each needs one AI call will throw a `System.LimitException` at record 101. Bulk AI processing must be refactored to async before going to production.
4. **ModelsAPI Code200 can be null on non-200 responses** — the generated type has separate fields for each HTTP status bucket. Code that assumes `response.Code200` is always populated will produce a NullPointerException on model errors, throttle responses, or quota-exceeded replies.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| ModelsAPI call scaffold | Typed Apex calling createChatGenerations or createGenerations with null-safe response parsing |
| Platform Cache token wrapper | Cache-aside Apex class for JWT token storage and reuse |
| Queueable chain design | AiProcessQueueable structure with bounded slice, enqueue-next logic, and termination guard |
| Review findings | Identified callout budget risks, missing cache strategies, and bulk-processing antipatterns |

---

## Related Skills

- `apex/platform-cache` — detailed patterns for Cache.Org design, TTL selection, key namespacing, and cache-aside wrappers
- `apex/apex-queueable-patterns` — Queueable chain structure, re-enqueue patterns, and error handling for async jobs
- `apex/callouts-and-http-integrations` — general Apex callout patterns, Named Credentials, and HTTP request construction
- `apex/governor-limits` — full governor limit reference for callout budgets, heap limits, and transaction boundaries
- `agentforce/model-builder-and-byollm` — for configuring which AI models are available in the org for aiplatform.ModelsAPI

Related Skills

scim-provisioning-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when designing or reviewing SCIM-based user lifecycle provisioning into Salesforce from Okta, Azure AD / Entra, or another IdP — create/update/deactivate, group-to-permission-set mapping, attribute mapping, and deprovisioning semantics. Triggers: 'scim provisioning', 'okta scim salesforce', 'entra salesforce provisioning', 'user deactivation automation', 'group to permission set mapping'. NOT for SSO/authentication setup (see single-sign-on skills).

apex-managed-sharing-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Grant row-level access programmatically via __Share records when declarative sharing rules cannot express the policy. NOT for OWD, role hierarchy, or criteria-based sharing rule design.

omnistudio-lwc-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when embedding OmniScripts in Lightning Web Components, registering custom LWC elements inside OmniScript screens, or calling OmniScript/Integration Procedures from LWC. Triggers: embed omniscript in LWC, custom LWC element in OmniScript, call OmniScript from Lightning page, omnistudio-omni-script tag, seed data JSON, OmniScript launch from LWC. NOT for standalone LWC development, standard Flow embedding, or OmniScript-to-OmniScript embedding.

integration-procedures

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when building, reviewing, or debugging OmniStudio Integration Procedures. Triggers: 'integration procedure', 'IP', 'HTTP action', 'DataRaptor', 'rollbackOnError', 'failureResponse'. NOT for Apex-only integrations unless the main design choice is whether OmniStudio is still appropriate.

integration-procedure-cacheable-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when designing Integration Procedures (IPs) with platform cache to cut latency and callout load. Covers cache key design, TTL selection, per-user vs org-wide partitions, invalidation on data changes, and safe fallback on cache miss/stale. Does NOT cover general IP authoring (see omnistudio-error-handling-patterns) or LWC client-side caching.

lwc-imperative-apex

8
from PranavNagrecha/AwesomeSalesforceSkills

Call Apex methods imperatively from LWC — on button click, lifecycle hooks, or conditional logic. Covers import syntax, cacheable vs non-cacheable, async/await patterns, error handling, loading states, and Promise.all. NOT for wire service (use wire-service-patterns) and NOT for testing Apex mocks (use lwc-testing).

slack-salesforce-integration-setup

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when setting up or troubleshooting the Salesforce for Slack managed app — including connecting a Salesforce org to a Slack workspace, configuring the three-party admin handshake, linking Slack channels to Salesforce records, enabling record preview sharing, and managing org-level limits. Triggers on: Salesforce for Slack app not connecting, Slack org connection setup, Salesforce record sharing in Slack, Slack workspace admin approval, connecting Salesforce to Slack. NOT for building custom Slack apps or Slack bots (separate development platform), not for Slack Workflow Builder Salesforce connector (use slack-workflow-builder skill), not for Flow-based Slack messaging (use flow-for-slack skill).

sis-integration-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when designing or implementing an integration between a Student Information System (SIS) — such as Ellucian Banner, Ellucian Colleague, Anthology Student, Oracle PeopleSoft Campus Solutions, or Workday Student — and Salesforce Education Cloud. Covers the canonical Education Cloud data model objects (AcademicTermEnrollment, CourseOfferingParticipant, CourseOfferingPtcpResult, LearnerProfile, PersonAcademicCredential), external ID / upsert keying strategies using SIS-native identifiers (Banner PIDM, PeopleSoft EMPLID), batch nightly upsert patterns, Change Data Capture (CDC) for enrollment status writeback, and MuleSoft/middleware watermark patterns. Trigger keywords: SIS integration, Banner integration, PeopleSoft integration, Education Cloud data model, enrollment sync, grade writeback, AcademicTermEnrollment, LearnerProfile upsert. NOT for Salesforce Admissions Connect application processing, Financial Aid integration, Learning Management System (LMS) integrations, or general ETL tooling not involving Education Cloud objects.

salesforce-to-salesforce-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill to implement Salesforce-to-Salesforce integration patterns — covering the native S2S feature, API-based cross-org sync, Platform Event bridging, and Salesforce Connect Cross-Org adapter. Trigger keywords: Salesforce to Salesforce integration, cross-org data sharing, S2S feature, cross-org Platform Events, Salesforce Connect cross-org. NOT for multi-org strategy or architecture decisions (use architect/multi-org-strategy), single-org data sharing, or external (non-Salesforce) system integration.

real-time-vs-batch-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

When to use this skill: choosing between real-time (synchronous callouts, Platform Events, CDC, Pub/Sub API) and batch (Bulk API 2.0, scheduled ETL) integration patterns. Trigger keywords: should I use real-time or batch, how to sync high-volume data, when to use Platform Events vs Bulk API, integration latency vs volume tradeoff. NOT for Batch Apex internals (use batch-apex-patterns), NOT for MuleSoft middleware design (use middleware-integration-patterns), NOT for CDC field tracking configuration.

platform-events-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when publishing Platform Events from external systems via REST API, subscribing to Platform Events from outside Salesforce via CometD or Pub/Sub API, designing replay ID strategy for durable external consumers, or handling high-volume event delivery guarantees. Trigger keywords: 'external publish platform event', 'CometD subscribe', 'Pub/Sub API', 'replay ID external', 'durable subscription', 'RetainUntilDate'. NOT for Apex-only event publishing or triggering (use platform-events-apex). NOT for Change Data Capture external subscription (use change-data-capture-integration).

middleware-integration-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when selecting or comparing middleware / iPaaS tools (MuleSoft, Dell Boomi, Workato, Informatica) for Salesforce connectivity, or when determining whether a scenario requires middleware at all versus native Salesforce capabilities. Triggers: 'which iPaaS should I use', 'MuleSoft vs Boomi vs Workato', 'when do I need middleware for Salesforce', 'message transformation orchestration middleware'. NOT for MuleSoft Anypoint Salesforce Connector configuration (use mulesoft-salesforce-connector). NOT for API-led connectivity layer design (use api-led-connectivity). NOT for native Salesforce-to-Salesforce integration, Platform Events, or CDC.