Configuring Salesforce Email-to-Case: Standard vs On-Demand mode selection, routing address setup, email threading via Lightning tokens, auto-response rules, attachment limits, and per-address case field defaults. Trigger keywords: email-to-case, routing address, on-demand email-to-case, email threading, case from email, email agent, routing address setup, Case.settings-meta.xml, EmailToCaseRoutingAddress, emailServicesAddress, isVerified, caseOrigin, enableThreadTokenInBody, useEmailHeadersForThreading, overEmailLimitAction, unauthorizedSenderAction, enableE2CAttachmentAsFile, saveEmailHeaders, newEntityRecordType, casePriority, EmailMessage.EmailRoutingAddressId, auto-response loop. NOT for the wider case layer (queues, escalation rules, case teams, entitlements) - use admin/case-management-setup. NOT for routing case work items to agents after creation - use admin/omni-channel-routing-setup. NOT for the email templates or letterheads themselves - use admin/email-templates-and-alerts.
This skill activates when an admin needs to configure or troubleshoot Salesforce Email-to-Case: enabling the feature, choosing between Standard and On-Demand mode, creating and verifying routing addresses, ensuring customer reply emails thread into the originating case rather than creating duplicates, and setting per-address case defaults and auto-response behavior.
Before Starting
Gather this context before working on Email-to-Case configuration:
Which Email-to-Case mode is appropriate? On-Demand is the default choice for most orgs. It uses Salesforce-hosted Apex Email Services and requires no locally installed agent. Standard Email-to-Case requires a downloadable Java agent running on a server inside the company firewall; it keeps email traffic internal but adds operational overhead. Choose Standard only if security policy or data residency rules prohibit email routing through Salesforce infrastructure.
What are the attachment size limits? On-Demand Email-to-Case accepts an inbound message of up to 35 MB in total (body + attachments + HTML). Because MIME transfer encoding inflates a message by up to 33% in transit, the effective attachment ceiling is approximately 25 MB. Messages over the total limit are rejected at the routing address. There is no separate per-attachment cap — 10 MB and 25 MB are the former org-wide totals (pre-Summer '14 and pre-Winter '21 respectively), not current per-attachment rules.
Is email threading the top priority? Threading is the single most commonly misconfigured behavior. Salesforce puts a thread token in the body and/or subject of outgoing case email — which settings control that depends on whether the org uses Lightning Threading, and the two switch pairs are mutually exclusive (see Core Concepts). When a customer replies, Salesforce reads the token to locate the parent case and adds the reply as an EmailMessage. If the token is stripped by a mail server or a security gateway, useEmailHeadersForThreading is the only thing standing between the org and a new case per reply.
Are auto-response rules needed? Auto-response rules only fire when the active case assignment rule fires. Confirm an assignment rule is active and will match the cases created by Email-to-Case before configuring auto-response rules.
Questions to Ask Before Configuring
Ask these before opening Setup. Each one has a gotcha behind it, and an agent that skips them
produces a settings file that deploys cleanly and silently drops customer mail.
Ask
Why it matters
What a good answer adds
"Which public addresses do customers actually write to, and does the same mailbox forward to more than one place?"
Each address is one routingAddresses element; a mailbox that forwards twice duplicates every case, and two elements sharing an emailAddress have no deterministic configuration
The channel list, one forwarding rule each, checked by the duplicate-address ERROR in the checker
"Which queue owns each channel's cases?"
caseOwner on a routing address writes the org-level defaultCaseOwner, so a second address setting it overwrites the first (gotchas #6)
Ownership expressed as caseOrigin per address plus assignment rule entries, not caseOwner
"Is the Case.Origin picklist value for each channel already active in the org?"
caseOrigin is the only per-address value an assignment rule can read; a value that is not in the picklist stamps something nobody can filter on
The picklist additions that must deploy before or with the settings file
"Is this org on Lightning Threading or legacy threading?"
Two mutually exclusive pairs of token switches exist and the wrong pair is inert (gotchas #8)
The one pair to set, plus useEmailHeadersForThreading as the gateway fallback
"What should happen to mail we refuse — bounce it or drop it?"
unauthorizedSenderAction and overEmailLimitAction both accept Discard, which leaves no Case, no EmailMessage and no bounce (gotchas #9)
A deliberate Bounce / Requeue choice instead of an invisible failure mode
"Who sends the acknowledgement, and does that address forward back to us?"
Any auto-response sender that reaches a routing address is an unbounded case-creation loop; so is a vacation responder on the forwarding mailbox
A no-reply sender, plus the mail-server rule audit the checker cannot see
"Which record type and which starting priority should each channel's cases be created on?"
newEntityRecordType and casePriority are stamped at creation, before any rule or Flow runs. The record type decides the support process and status ladder; the priority is never null afterwards, so a null-guarded priority stamp downstream never fires (gotchas #14, #15)
A record type per channel in Case.<DeveloperName> form on an API 64.0+ manifest, and a declared starting tier per channel
"Does anyone need email headers for a future security investigation?"
saveEmailHeaders captures envelope data at processing time and cannot be backfilled (gotchas #12)
Headers on from day one, and EmailMessage.Headers inside the org's retention scope
What a proper configuration adds over just switching Email-to-Case on: every channel is a reviewable
element in settings/Case.settings-meta.xml rather than an unowned Setup checkbox, ownership is
decided once in the assignment rule instead of racing through a shared org-level field, refused mail
leaves a trace, and the reply loop is caught by a script before it is caught by the send limit.
Core Concepts
Standard vs On-Demand Email-to-Case
Email-to-Case has two operating modes with distinct infrastructure requirements:
Standard Email-to-Case uses a locally installed Java agent. The agent polls the company mail server, converts inbound emails to cases, and pushes them to Salesforce via the API. Email traffic travels from the customer to the company mail server and remains inside the corporate network — it never routes through Salesforce infrastructure before case creation. This matters for orgs with strict data residency or email content classification requirements. The agent requires a server to run on, must be kept online, and consumes Salesforce API calls for every email processed.
On-Demand Email-to-Case uses Salesforce-hosted Apex Email Services. Salesforce generates a unique routing address in the format [unique-id]@[instance].salesforce.com. The company configures its mail server to forward inbound email from the public support address (e.g., support@company.com) to this Salesforce address. Email content, including attachments, travels through Salesforce's email infrastructure before the case is created. No local agent is required. This is the recommended mode for the majority of orgs.
Size behaviour differs by mode because the enforcement point differs. On-Demand enforces Salesforce's inbound message limit at the routing address: 35 MB total per message, with an effective attachment ceiling of roughly 25 MB once MIME encoding overhead is applied. Standard Email-to-Case receives mail at the company's own mail server, so the first size gate is whatever that server enforces; the agent then creates the case through the API. Do not quote a per-attachment cap for either mode — Salesforce documents a total-message limit, not a per-attachment one.
Email Threading: Two Switch Pairs and a Header Fallback
An outgoing case email carries a thread token in the body, the subject, or both. Which elements
control that depends on the org's threading mode, and the Metadata API guide is explicit that the two
pairs are mutually exclusive:
appends the token when an agent sends from the Lightning email composer
enableThreadIDInBody / enableThreadIDInSubject
orgs not using Lightning Threading
inserts the Thread ID in the body / subject line
useEmailHeadersForThreading
either
matches a reply from incoming email metadata when token-based threading finds nothing
Setting the pair that does not apply to the org changes nothing at all. useEmailHeadersForThreading
is the second chance when a mail gateway has stripped the token, and is the one switch worth turning
on in every org. Do not verify threading on EmailMessage.ThreadIdentifier: the Object Reference
states that field "is not used by On-Demand Email-to-Case". Verify on EmailMessage.ParentId —
query in references/metadata-examples.md.
When a customer replies, Salesforce's inbound processing inspects the reply for a matching token. If found, the reply is appended to the originating case as a new Email Message record. If not found, a new case is created. Threading failures occur when:
The mail server or security gateway strips or modifies the reference string in the body or subject.
The customer uses a mail client that strips quoted content (removing the body token) AND modifies the subject line (removing the subject token).
The routing address is misconfigured and inbound mail is not matched to the correct Email-to-Case configuration.
Always test threading end-to-end before go-live: send an inbound email, confirm case creation, reply from the case in Salesforce, have the reply delivered to the customer's inbox, and reply back. The reply must add an Email Message to the original case, not create a new case.
Routing Addresses
A routing address is a per-mailbox Email-to-Case configuration record. Each routing address defines:
The external email address customers use (emailAddress — the address your mail server forwards from).
The Salesforce-generated target address (On-Demand mode only) that the mail server forwards to.
Default values applied to cases created via this address: Case Origin, Status, Priority, and optionally a queue or owner. casePriority is not skippable — the org rejects an address without it (gotchas #15).
The record type new cases land on, via newEntityRecordType — Case.<DeveloperName>, API 64.0 and later only (gotchas #14). This is the only deterministic record-type control on the channel; keepRecordTypeOnAssignmentRule does not cover it.
Whether an auto-response is sent and which auto-response rule entries apply.
An org can have multiple routing addresses, one per inbound support channel (e.g., support@, billing@, returns@). Each address creates cases with its own defaults, allowing cases to be pre-classified by channel before assignment rules run.
Two fields are read-only and never come from your source file: emailServicesAddress (the
Salesforce-generated address the mailbox forwards to) and isVerified. A freshly deployed routing
address therefore always lands unverified, and Salesforce accepts no mail at it until someone clicks
the verification link in the org.
What the address stamps on the Case, and what it does not.caseOrigin sets Case.Origin,
casePriority sets Case.Priority, and caseOwner + caseOwnerType reach Case.OwnerId — but by
writing the single org-level defaultCaseOwner, so only one address can use them meaningfully.
There is no routing-address field on Case at all; the address is recorded one object over as
EmailMessage.EmailRoutingAddressId. That makes Case.Origin the only per-channel hand-off an
assignment rule can read, which is the rule design shown in references/metadata-examples.md.
Auto-Response Rules and Assignment Rule Dependency
Auto-response rules send confirmation emails to customers when cases are created. They are not independent: an auto-response rule entry fires only when the active case assignment rule fires for the same case creation event. If no assignment rule is active, or if no rule entry matches the incoming case, the auto-response will not fire regardless of auto-response rule configuration.
This dependency is the most commonly misdiagnosed "auto-response not sending" issue.
Common Patterns
Pattern: On-Demand Email-to-Case with Verified Threading
When to use: Configuring Email-to-Case for the first time in an org with no local email agent requirement.
How it works:
Navigate to Setup → Email-to-Case. Click Edit and enable Email-to-Case. Select "Enable On-Demand Service" to activate On-Demand mode.
Save. Return to Email-to-Case settings. Under Routing Addresses, click New.
Enter the routing address name (for display), the email address customers use (e.g., support@company.com), and the default Case Origin, Status, and Priority for cases created from this address.
Save the routing address. Salesforce generates a Salesforce-hosted email address. Copy this address.
Configure the company mail server to forward inbound mail from support@company.com to the Salesforce-generated address.
Click "Send Verification Email" on the routing address to confirm Salesforce can receive at that address. Verify the address in the confirmation email.
Test threading: send an email to support@company.com, confirm a case is created in Salesforce, send a reply from the case, deliver it to an inbox, and reply back. The reply must append to the original case as an Email Message, not create a new case.
Why not Standard Email-to-Case: Standard requires a local agent, server maintenance, and consumes API calls per email. On-Demand is fully hosted and requires only a mail forwarding rule.
Pattern: Multiple Routing Addresses for Channel-Based Case Classification
When to use: The org has multiple inbound support email addresses (e.g., billing, technical, returns) and needs cases created from each address to have different default fields or route to different queues.
How it works:
Create one routing address per inbound channel, each with appropriate default Case Origin, Status, and Priority.
In the case assignment rule, add rule entries that match on Case Origin (or a custom field set by the routing address) and route to the appropriate queue.
Each address generates its own Salesforce-hosted routing address (On-Demand). Configure a separate forwarding rule on the mail server for each address.
Test each channel independently to confirm cases arrive with correct defaults.
Why not a single routing address with automation: A single address cannot set per-channel defaults natively. Using multiple addresses keeps classification at the point of creation rather than requiring post-creation automation.
Decision Guidance
Situation
Recommended Approach
Reason
New Email-to-Case setup with no local infrastructure requirement
On-Demand Email-to-Case
No agent to install or maintain; fully Salesforce-hosted
Org policy prohibits email content routing through external infrastructure
Standard Email-to-Case with local agent
Email stays inside corporate network before case creation
Customer replies create new cases instead of threading
Verify Lightning token in outgoing email body and subject; check mail server for token stripping
Threading depends on token surviving round-trip through customer's mail client and company gateway
Inbound email rejected in On-Demand mode for size
Check the message total (body + attachments + HTML) against 35 MB, allowing ~33% MIME inflation; direct large files to a Files/portal upload link in the auto-response
Salesforce enforces a 35 MB total inbound message limit at the routing address, giving an effective attachment ceiling of ~25 MB
Auto-response email not sent on case creation
Confirm an active assignment rule exists and matches the case
Auto-response only fires when assignment rule fires
Cases created via Email-to-Case land with default case owner, not a queue
Add a catch-all entry to the assignment rule pointing to the correct queue
Assignment rule must be active and matching for cases to route to queues
Routing address verification email never arrives
Check spam filters, mail server logs, and that the forwarding rule is active
Salesforce sends the verification to the Salesforce-generated address; mail server must be forwarding
Recommended Workflow
Read the org before writing anything.sf project retrieve start --metadata "Settings:Case" "AssignmentRules:Case" "AutoResponseRules:Case". routingAddresses is a full-replacement list, so every later edit must start from what the org actually has (references/gotchas.md #7).
Answer the seven questions above and fill in templates/email-to-case-configuration-template.md: channels, the caseOrigin value each stamps, the owning queue, the acknowledgement sender, the threading mode. Confirm the mode choice — On-Demand unless data residency policy forbids it.
Shape the metadata from references/metadata-examples.md: the emailToCase block with one routingAddresses element per channel, the matching Case.assignmentRules entries keyed on Case.Origin, and the package.xml naming Settings:Case explicitly (the wildcard does not work for an individual setting).
Run the checker — python3 scripts/check_email_to_case_configuration.py --manifest-dir <dir> --verbose. It exits 1 on ERRORs only; add --strict to fail on the advisory WARNs too. Clear every ERROR (duplicate emailAddress, caseOwner without caseOwnerType, more than one address setting caseOwner, auto-response sender equal to a routing address, E2C-PRI-01 a missing casePriority, E2C-RT-01 a bare newEntityRecordType, E2C-RT-02 that element on a package.xml below API 64.0). Justify or fix each WARN — isVerified reports org state that metadata cannot set at all.
Deploy, then finish the setup that metadata cannot do: copy each emailServicesAddress out of Setup, create one forwarding rule per channel, disable any auto-reply on the forwarding mailbox, send the verification email, and confirm each address reads Verified. The checklist is in references/metadata-examples.md.
Run the three tests from references/metadata-examples.md: the threading round-trip through the production mail gateway asserted on EmailMessage.ParentId, the routing-address/origin query, and the loop test (one email per address, case count must stop at one).
Hand over. Record the public address to emailServicesAddress mapping, the verification dates, and the threading mode in the org runbook — the org will not hand emailServicesAddress back if an address is ever deleted. Work through the Review Checklist below.
Review Checklist
Run through these before marking Email-to-Case configuration complete:
Email-to-Case feature is enabled in Setup and mode (On-Demand vs Standard) is documented and justified
Each routing address has the external email address, default Case Origin/Status/Priority, and a verified Salesforce-hosted target address (On-Demand) or agent configuration (Standard)
Mail server forwarding rules are active and tested: inbound email to each support address reaches Salesforce and creates a case
Email threading tested end-to-end: customer reply to a case email adds an Email Message to the original case and does not create a new case
Active case assignment rule exists with at least one entry matching Email-to-Case–created cases; catch-all entry routes remaining cases to a queue rather than default owner
If auto-response rules are configured: assignment rule fires for the same case creation events; auto-response rule entry has a valid email template and a sender address that is not the routing address (to prevent email loops)
Attachment size limits communicated to support team: On-Demand accepts up to 35 MB total inbound message size, i.e. roughly 25 MB of attachments after MIME encoding overhead; there is no per-attachment cap
settings/Case.settings-meta.xml was retrieved from the target org before editing, and the routing-address count in the file to be deployed is not lower than the count in the org
At most one routing address sets caseOwner, and it sets caseOwnerType alongside it; per-channel ownership is expressed as caseOrigin plus assignment rule entries
Every caseOrigin value used by a routing address exists and is active in the Case.Origin picklist
Only the threading switch pair matching the org's threading mode is set; useEmailHeadersForThreading is on
unauthorizedSenderAction and overEmailLimitAction are a deliberate choice, and Discard is used only where someone has signed off on losing the message
saveEmailHeaders is true on every routing address
Every routing address carries casePriority, the value is a deliberate starting tier for that channel, and nothing downstream derives priority behind a "is blank" guard
If newEntityRecordType is used: every value is Case.<DeveloperName>, the record type is active on Case, and the package.xml<version> is 64.0 or later
Threading verified on EmailMessage.ParentId, not on ThreadIdentifier (blank for On-Demand Email-to-Case by design)
python3 scripts/check_email_to_case_configuration.py --manifest-dir <dir> --verbose reports zero ERRORs and every WARN is justified
Salesforce-Specific Gotchas
Non-obvious platform behaviors that cause real production problems:
The On-Demand size limit is per-message, not per-attachment — and the number you remember is probably a retired one — Salesforce rejects an inbound On-Demand message once the total (body + attachments + HTML) exceeds 35 MB. MIME transfer encoding inflates the payload by up to 33%, so the practical attachment budget is about 25 MB. 25 MB was the org-wide total before Winter '21 and 10 MB was the total before Summer '14; both numbers survive in older blog posts and in model memory as fictitious per-attachment caps. Quote 35 MB total / ~25 MB effective, and never promise a per-attachment threshold.
Routing address verification is required before inbound email is accepted — Until the routing address is verified (by clicking the link in the Salesforce-sent verification email), Salesforce will not accept inbound email at that address. Forwarding can be configured on the mail server before verification, but emails will bounce or be dropped until verification completes.
Auto-response rule loops when From address equals routing address — If the auto-response rule is configured to send from the same email address that the routing address is configured to receive at (e.g., both are support@company.com), the auto-response email will arrive back at Salesforce and create another case, which triggers another auto-response, creating an infinite loop. Always use a different From address or a no-reply address for auto-response rules.
Lightning thread token stripping by security gateways — Corporate email security gateways (e.g., Proofpoint, Mimecast) sometimes strip or modify the reference string in the email body or subject line as part of link-rewriting or content inspection. This silently breaks threading. Test the full round-trip through the production mail gateway before go-live, not just against a direct SMTP relay.
Standard Email-to-Case agent consumes API calls — The local agent converts each email to a case via the Salesforce API. High-volume inbound mail can exhaust the org's daily API call limit. Monitor API usage after go-live if using Standard mode in a high-volume environment.
caseOwner is an org-level field wearing a per-address costume — the Metadata API guide states that setting it on a routing address writes CaseSettings.defaultCaseOwner. Give a second address its own owner and the first one's is overwritten, with no deploy warning. Route on Case.Origin instead.
Deploying a partial settings file deletes the channels it omits — routingAddresses is a full-replacement list, and emailServicesAddress is read-only, so a deleted address cannot be restored to its old Salesforce-generated value. Always retrieve first.
Discard is genuinely silent — both unauthorizedSenderAction and overEmailLimitAction accept it, and a discarded message produces no Case, no EmailMessage and no bounce. Nobody can prove the customer wrote in.
newEntityRecordType is version-gated and object-qualified, and the guide says neither — a bare <newEntityRecordType>Support</newEntityRecordType> fails with In field: newEntityRecordType - no RecordType named Support found even when that record type exists and is active; Case.Support resolves. The element itself is rejected below API 64.0 with Property 'newEntityRecordType' not valid in version 63.0, so the package.xml<version> must be raised with it. The field's guide entry (api_meta L112078) carries no version note, unlike fallbackQueue (56.0) and isPermsetControlled (61.0) beside it. UNVERIFIED (2026-09-12): both proven live, not in the guide. Detail in references/gotchas.md #14.
casePriority is required by the org and optional in the guide — an address without it is rejected with EmailToCaseRoutingAddress[support@acme.example]: Missing casePriority, though api_meta L112039 marks the field neither Required nor Optional. UNVERIFIED (2026-09-12): proven live. The consequence outlives the deploy: every email case is created with Priority already set, so a null-guarded priority stamp downstream never fires. Detail in references/gotchas.md #15.
Deeper treatment, with the platform behaviour behind each, in references/gotchas.md (15 entries).
Output Artifacts
Artifact
Description
settings/Case.settings-meta.xml
The emailToCase block: mode, threading and failure-action switches, and one routingAddresses element per channel; deployable as Settings:Case
Email-to-Case routing address
Configured routing address record with external email, Salesforce target address, and case defaults; verification confirmed
Address map
Public address → emailServicesAddress → caseOrigin → owning queue, with verification dates, for the org runbook
Mail server forwarding rule
Forward rule on company mail server routing inbound mail from the support address to the Salesforce-generated address
Threading test record
Test case and Email Message records demonstrating that a customer reply threads correctly into the parent case
Assignment rule update
Active case assignment rule with entries that match Email-to-Case–created cases and route them to the correct queue
Auto-response rule (if applicable)
Active auto-response rule entry with email template; From address is not the routing address
Reference Files
File
Read it when
references/metadata-examples.md
Writing or reviewing Case.settings-meta.xml, the routing-address-to-assignment-rule hand-off, the forwarding and verification checklist, or the threading / routing / loop verification queries
references/gotchas.md
Mail is being dropped, threading broke, a channel vanished after a deploy, or ownership is wrong on one channel
references/examples.md
Working end-to-end setups: one mailbox, multiple channels, and how to catch the auto-response loop in the first five minutes
references/llm-anti-patterns.md
Reviewing AI-generated Email-to-Case guidance, especially any quoted attachment size number
references/well-architected.md
Justifying On-Demand vs Standard, single vs multiple addresses, or auto-response vs Flow, and for the source list
Related Skills
admin/case-management-setup — the wider case layer (queues, escalation, entitlements, Web-to-Case); this skill closes that skill's open "routing-address to queue mapping" question via Case.Origin
admin/assignment-rules — the Case.assignmentRules and Case.autoResponseRules files themselves: criteria grammar, entry order, and the senderEmail this skill must never let equal a routing address
admin/email-templates-and-alerts — org-wide email addresses and the Classic templates an auto-response entry points at
admin/queues-and-public-groups — references/queue-behaviour-matrix.md, the email / doesSendEmailToMembers pair that stacks with notifyOwnerOnNewCaseEmail
admin/business-hours-and-holidays — the SLA clock that starts when an inbound email creates the case
admin/email-service-inbound — a different feature: Apex Email Services with Messaging.InboundEmailHandler, for inbound mail that must run custom code. On-Demand Email-to-Case is Salesforce's own hosted email service and needs no handler; write one only when case creation is not what you want
admin/case-feed-send-email-action — the outbound half: the Send Email quick action agents reply from, and its own file limits
admin/email-deliverability-strategy — SPF, DKIM and DMARC on the domain that forwards into the routing address
admin/omni-channel-routing-setup — pushing the created case to an available agent; routingFlow and fallbackQueue on a routing address are the entry point
admin/permission-set-architecture — the grants that isPermsetControlled requires before it stops locking everyone out
Use this skill when writing test-first, behavior-driven acceptance criteria in Given/When/Then format for a Salesforce user story. Covers happy path, edge cases, negative paths, permission boundaries, and data-state preconditions so the AC block can drive UAT scripts and Apex test design downstream. Trigger keywords: given when then, gherkin, behavior driven AC, test first acceptance criteria, scenario outline, BDD acceptance criteria. NOT for the user-story format itself (use admin/user-story-writing-for-salesforce). NOT for UAT script writing (use admin/uat-test-case-design). NOT for Apex test method generation (use agents/test-class-generator). NOT for high-level UAT planning (use admin/uat-and-acceptance-criteria). More triggers: acceptance criteria record, ac_id, req_id on a criterion, artefact under test, negative case for a rule-type requirement, no-match fall-through criterion, oracle for a Then clause, test type apex flow manual, criteria linter, check_ac_format.py, --manifest-dir.
Task and Event objects: polymorphic WhatId/WhoId, Activity object model, ActivityHistory vs OpenActivity, activity timeline customization, bulk task creation, Einstein Activity Capture boundaries. NOT for turning on EAC or calendar sync — use admin/einstein-activity-capture-setup. NOT for Email-to-Case — use admin/case-management-setup. Covers ActivitiesSettings metadata, enableActivities, shared Task/Event custom fields and FLS, TaskStatus value sets, Shared Activities and TaskRelation/EventRelation, recurring and child activities, and partial-success bulk DML on Task.
Design Invocable Apex actions that return deterministic, agent-friendly errors instead of surfacing raw exceptions to the LLM. NOT for authoring the action itself — @InvocableMethod schema, labels, security context — use agentforce/custom-agent-actions-apex. NOT for the Apex tests that force each error branch — use agentforce/agent-action-unit-tests.
Use when designing how an Agentforce agent extracts structured input parameters (slots) from a user's natural-language utterance to invoke an action. Triggers: 'agent extract date from user', 'agent action argument extraction', 'agentforce slot filling', 'agent invocable input mapping', 'agent fails to fill required parameter'. NOT for action authoring (use agentforce/agent-actions) or for prompt-template variable binding (use agentforce/prompt-builder-templates).
Apex test patterns for @InvocableMethod agent actions: per-reason-code branch coverage, bulk safety, callout mocking, deterministic assertions. NOT for testing whether the agent routes to the right topic or answers well — use agentforce/agent-testing-and-evaluation. NOT for designing the error envelope the tests assert on — use agentforce/agent-action-error-handling.
Designing or reviewing Agentforce actions: Flow actions, Apex invocable actions, prompt-template actions, action naming, input and output contracts, confirmation requirements, and safe error behavior. Triggers: 'agent actions', 'build an agent that can look up an order', 'make the agent able to check order status', 'give the agent a capability', 'agent that can retrieve a record', 'flow action for agent', 'agent invocable action', 'action schema design'. NOT for writing the Apex class itself — use agentforce/custom-agent-actions-apex. NOT for the reason_code error envelope that stops an agent retry loop — use agentforce/agent-action-error-handling.