Email Studio API
Email Studio exposes Actions and Data objects as its package API. Controllers, Filament resources, listeners, and other packages should call these Actions instead of writing directly to the email tables.
Registering Templates
Section titled “Registering Templates”Use RegisterEmailTemplateAction when a package owns a template definition.
use Capell\EmailStudio\Actions\RegisterEmailTemplateAction;
RegisterEmailTemplateAction::run( key: 'forms.confirmation', name: 'Form confirmation', variables: ['name', 'submission_reference'], description: 'Sent after a successful form submission.', packageName: 'capell-app/form-builder', siteId: null, siteScopeKey: 'global',);Registrations are upserted by package, key, and site scope. They describe the expected template contract; the actual approved sendable content lives in EmailTemplate and EmailTemplateVariant.
Sending Email
Section titled “Sending Email”SendEmailAction is the canonical entrypoint.
use Capell\EmailStudio\Actions\SendEmailAction;use Capell\EmailStudio\Data\EmailAddressData;use Capell\EmailStudio\Data\EmailHeaderData;use Capell\EmailStudio\Data\SendEmailData;use Spatie\LaravelData\DataCollection;
SendEmailAction::run(new SendEmailData( templateKey: 'forms.confirmation', to: new DataCollection(EmailAddressData::class, [ ]), cc: new DataCollection(EmailAddressData::class, []), bcc: new DataCollection(EmailAddressData::class, []), siteId: 12, siteScopeKey: 'site:12', emailProfileId: null, variables: [ 'name' => 'Customer Name', 'submission_reference' => 'FS-1001', ], headers: new DataCollection(EmailHeaderData::class, []), triggeredByType: 'form_submission', triggeredById: 1001, queue: true, locale: 'en',));The Action:
- resolves a profile from the requested site scope;
- resolves an approved template;
- resolves an active variant for the requested or current locale;
- renders declared variables;
- creates the message and recipient rows;
- applies suppressions;
- dispatches
SendEmailJobwhen queueing is enabled.
Pass queue: false only for tests or controlled workflows that need immediate delivery.
Rendering A Variant
Section titled “Rendering A Variant”Use RenderEmailTemplateAction when the admin UI needs a preview.
use Capell\EmailStudio\Actions\RenderEmailTemplateAction;use Capell\EmailStudio\Data\EmailContextData;
$rendered = RenderEmailTemplateAction::run( variant: $variant, context: new EmailContextData( variables: ['name' => 'Customer Name'], preview: true, ),);Preview mode leaves missing markers visible. Production mode throws EmailTemplateRenderingException when a variable is missing or undeclared.
Resolving Variants
Section titled “Resolving Variants”Use ResolveEmailTemplateVariantAction to select the sendable content for a template.
$variant = ResolveEmailTemplateVariantAction::run( template: $template, siteScopeKey: 'site:12', locale: 'en',);Resolution order:
- requested site scope before global;
- requested locale before neutral locale;
- latest version among matching active variants.
When no locale is supplied, the resolver only returns neutral variants. SendEmailAction supplies Laravel’s current locale by default.
Suppressions
Section titled “Suppressions”Use SuppressEmailAddressAction to add or reactivate a suppression.
use Capell\EmailStudio\Actions\SuppressEmailAddressAction;use Capell\EmailStudio\Enums\SuppressionReason;
SuppressEmailAddressAction::run( reason: SuppressionReason::Complaint, siteId: null, siteScopeKey: 'global', source: 'provider',);Use CheckEmailSuppressionAction when another integration needs to check before offering an email workflow.
Global suppressions apply to every site. Site-scoped suppressions apply only to that site scope.
Provider Adapters
Section titled “Provider Adapters”Providers implement EmailProviderAdapter.
use Capell\EmailStudio\Contracts\EmailProviderAdapter;use Capell\EmailStudio\Enums\EmailProviderType;use Capell\EmailStudio\Support\EmailProviderRegistry;
resolve(EmailProviderRegistry::class)->register( EmailProviderType::Fake, new CustomProviderAdapter(),);Adapters return ProviderSendResultData. A provider-level failure should return successful: false and a failure reason. If the adapter throws, DeliverEmailMessageAction records the message and queued recipients as failed.
Error Handling
Section titled “Error Handling”EmailStudioSendingException is thrown when:
- no recipients are provided;
- no profile is available;
- no approved template is available;
- no active variant is available;
- a provider adapter is not registered.
Provider transport failures are recorded on the message and recipients instead of bubbling through as unrecorded queue failures.