FAQs

Can I call subscriber invocable actions from async Apex or a batch?

If you're building custom Apex to manage subscriber list membership in bulk, our invocable actions support this. It's worth understanding how they're designed to work before building your batch though, as there are a few common mistakes that can cause issues.

If you're seeing errors, check the CM Settings tab in Salesforce and review the Maintenance Logs section, which captures issues we can detect on our end.

The Solution

Each subscriber action has its own method name. For example, adding a contact uses AddContactToSubscriberList.addContacts(). Other actions follow the same pattern with their own class and method, such as updating or removing a subscriber. The guidance below applies to all of them.

Call the action from execute, not finish
Subscriber actions belong in the execute method of your batch. This is where the record-by-record work happens.

Use direct = false for bulk operations
On actions that support it (such as AddContactToSubscriberList), setting direct = false (the default) queues your requests and lets the package's own ProcessAsyncRecordsBatch handle the Campaign Monitor API calls. This is the recommended approach for large volumes as it avoids stacking callouts inside your own batch transaction. Actions that don't support the flag always queue automatically.

Use direct = true only for small scopes
Where supported, direct = true will call the Campaign Monitor API synchronously in the same transaction. Your batch must implement Database.AllowsCallouts for this to work.

Don't mix DML and callouts in the same transaction
Salesforce doesn't allow HTTP callouts after you've already saved records in the same transaction. If you use direct = true, call the subscriber action before any insert, update, or delete in that execute run — or stick with direct = false and let the package queue handle the API work for you.

Build requests inside the for loop
Build your request objects as you iterate through records in execute. The queuing handles bulk safely on its own.

The general flow with direct = false looks like this:

  • Your batch execute method builds and calls the action per record (or small group)
  • Requests are queued as Queue_Item__c rows
  • ProcessAsyncRecordsBatch picks these up and handles the Campaign Monitor API calls
  • On finish, the queue rows are cleaned up and the batch chains if more work remains

We don't offer support for custom code builds, but if you've reviewed the above and are still seeing issues, check the Maintenance Logs on the CM Settings tab for any errors we've caught on our end.

Note: If you're sending transactional emails from a batch, the approach is different. See the related article below.

Related Articles

Related articles
How to guides
Contact Us