Beyond Built-In Triggers#
AcelleMail's built-in automation triggers — subscribes, date fields, tag additions, link clicks — cover most standard workflows. But complex products have events that exist only in your application: a user completes onboarding step 3, a free trial expires, a support ticket is resolved, a project milestone is reached.
API-driven automation lets you trigger email sequences from any event in any system, giving you full control over the exact conditions and timing of your email workflows.
The Architecture#
Your Application Event
→ HTTP POST to AcelleMail API (subscriber update / tag add)
→ AcelleMail Automation triggers on tag or field change
→ Email sequence begins
You don't push emails directly via API. Instead, you update subscriber state (tags, custom fields), and automations react to those state changes.
Setting Up API Access#
In AcelleMail, generate your API key:
- Go to Settings → API
- Click Create API Key
- Note your API endpoint (typically
https://your-acelle-domain.com/api/v1/)
Install the AcelleMail API client or use raw HTTP:
// Using Guzzle HTTP client
$client = new \GuzzleHttp\Client([
'base_uri' => 'https://mail.yourdomain.com/api/v1/',
'headers' => [
'Authorization' => 'Bearer ' . config('services.acelle.api_key'),
'Accept' => 'application/json',
],
]);
Example 1: Trigger a Trial Expiry Sequence#
Scenario: User's free trial expires. Trigger a 3-email upgrade sequence.
In your application (cron job or event listener):
// app/Console/Commands/ProcessTrialExpiries.php
public function handle(): void
{
$expiredTrials = User::where('trial_ends_at', '<=', now())
->where('converted', false)
->get();
foreach ($expiredTrials as $user) {
// Add tag to trigger automation
$this->acelleApi->addTagToSubscriber(
listUid: config('services.acelle.list_uid'),
email: $user->email,
tag: 'trial-expired'
);
// Update custom field with expiry date
$this->acelleApi->updateSubscriber(
listUid: config('services.acelle.list_uid'),
email: $user->email,
fields: [
'TRIAL_EXPIRED_DATE' => $user->trial_ends_at->format('Y-m-d'),
'PLAN_NAME' => $user->trial_plan,
]
);
}
}
In AcelleMail:
Trigger: Tag added = "trial-expired"
→ Send Email: "Your trial has ended — here's what you're missing"
Wait 2 days
→ Condition: Tag does NOT include "converted"
→ Send Email: "Still thinking it over? We can help."
Wait 3 days
→ Condition: Tag does NOT include "converted"
→ Send Email: "Final offer: 40% off your first month"
Example 2: Webhook Receiver for AcelleMail Events#
AcelleMail can also push events to your application via webhooks — subscriber opens, clicks, unsubscribes. This creates a two-way integration.
Register a webhook in AcelleMail:
- Go to Settings → Webhooks → Add Webhook
- URL:
https://yourapp.com/webhooks/acelle
- Events:
subscribe, unsubscribe, open, click
Your Laravel webhook receiver:
// routes/api.php
Route::post('/webhooks/acelle', [AcelleWebhookController::class, 'handle']);
// app/Http/Controllers/AcelleWebhookController.php
public function handle(Request $request): JsonResponse
{
$event = $request->input('event');
$email = $request->input('subscriber.email');
match ($event) {
'click' => $this->handleClick($email, $request->input('link_url')),
'unsubscribe' => $this->handleUnsubscribe($email),
default => null,
};
return response()->json(['status' => 'ok']);
}
private function handleClick(string $email, string $url): void
{
if (str_contains($url, '/pricing')) {
// Trigger lead score increment
LeadScoreJob::dispatch($email, 'clicked_pricing');
}
}
Example 3: Subscriber Upsert on Application Events#
Use Laravel's event system to keep AcelleMail in sync automatically:
// app/Listeners/SyncUserToAcelleMail.php
public function handle(UserRegistered $event): void
{
$user = $event->user;
Http::withToken(config('services.acelle.api_key'))
->post(config('services.acelle.endpoint') . 'subscribers', [
'list_uid' => config('services.acelle.list_uid'),
'email' => $user->email,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'fields' => [
'PLAN' => $user->plan,
'SIGNUP_DATE' => now()->format('Y-m-d'),
'ACCOUNT_TYPE' => $user->account_type,
],
'tag' => 'new-user', // triggers welcome automation
]);
}
Rate Limits and Error Handling#
AcelleMail's API has configurable rate limits. For bulk operations:
// Process in chunks to avoid rate limiting
$subscribers->chunk(100, function ($chunk) {
foreach ($chunk as $subscriber) {
try {
$this->syncToAcelle($subscriber);
usleep(100000); // 100ms delay between requests
} catch (\Exception $e) {
Log::error('AcelleMail sync failed', [
'email' => $subscriber->email,
'error' => $e->getMessage(),
]);
}
}
});
Debugging API-Triggered Automations#
When an automation doesn't fire as expected:
- Check subscriber state in AcelleMail: Is the tag actually present? Is the field populated?
- Check automation logs: Go to Automation → Your Automation → Logs to see trigger events
- Verify API response: Log the full response from AcelleMail's API — a 422 or 404 means the subscriber or list wasn't found
- Check timing: AcelleMail processes automation triggers asynchronously — allow up to 60 seconds after the API call
API-driven automations are the most powerful tool in your AcelleMail arsenal. Once mastered, you can build marketing workflows as sophisticated as any dedicated marketing automation platform.