---
title: "Sending a campaign — Campaigns for Laravel | Roundly"
description: "Create, address and dispatch a campaign with the fluent Campaigns facade — or prepare it now and start it later."
url: https://roundly-consulting.com/open-source/docs/campaigns-for-laravel/sending-campaigns
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Campaigns for Laravel](https://roundly-consulting.com/open-source/docs/campaigns-for-laravel.md)

# Sending a campaign

The Campaigns facade is the fastest way to create, address and send a campaign. create() takes the subject and the content and returns a fluent PendingCampaign builder; the campaign UUID is generated for you:

```php
use RoundlyConsulting\Campaigns\Facades\Campaigns;

$campaign = Campaigns::create('Our spring collection is here', '<p>Hello, the spring collection just landed.</p>')
    ->from('news@example.com', 'Example Shop')
    ->to(['ana@example.com', 'ben@example.com'])
    ->dispatch();                    // prepare + start in one call

// Follow it through its handle.
$progress = Campaigns::campaign($campaign->uuid)->progress();
$progress->percentage();   // share delivered so far, e.g. 42.5 — live while sending
$progress->failed;         // deliveries that failed
$progress->remaining();    // recipients with no outcome yet
$progress->isRunning();    // bool
$progress->isComplete();   // bool

// Cancel it and its batch; the cancelled Campaign comes back.
$campaign = Campaigns::cancel($campaign->uuid);
```

dispatch() prepares the campaign — opens its job batch, stores it with its recipients and marks it Pending — then starts it and returns the fresh Campaign.

## Builder methods

- from($address, ?$name) — the sender; the name defaults to the address. Without it, the stored send defaults apply — and with no from-address default either, the mailer’s global mail.from.
- to($recipients) — add recipients; additive. See Recipients.
- uuid($uuid) — use your own id instead of the generated one. A uuid another campaign already holds throws CampaignAlreadyExists: preparing never overwrites, or re-sends, an existing campaign.
- subject($subject) / content($content) — replace what you passed to create().
- onlyVerified(bool $onlyVerified = true) / viaContactType($type) — resolution rules for contacts and owners.
- prepare() — open the batch, store the campaign with its recipients and leave it Pending, without sending.
- dispatch() — prepare and start in one call.

## Prepare now, send later

```php
use RoundlyConsulting\Campaigns\Facades\Campaigns;

$campaign = Campaigns::create('Draft subject', 'Draft body')
    ->uuid('0b6f4c1e-8d2a-4f0e-9c3b-5a7d2e1f4b6c')          // your own id instead of a generated UUID
    ->subject('Our spring collection is here')               // replace the subject
    ->content('<p>Hello, the spring collection just landed.</p>')
    ->from('news@example.com')                               // the name defaults to the address
    ->to('ana@example.com')
    ->prepare();                                             // batch opened, status Pending, nothing sent

// Later — from a scheduled job or an admin action:
Campaigns::start($campaign->uuid);   // only a Pending campaign starts
```

prepare() stores the campaign with its recipients and returns it Pending. Start it with Campaigns::start() whenever you’re ready. Only a Pending campaign starts — starting one that is already sending, or has ended, throws InvalidCampaignTransition instead of queueing every recipient twice. That holds when two processes start it at the same moment too — a double-clicked button, two scheduler workers: the move to Processing is one atomic compare-and-set, and only its winner queues the recipients. A campaign with nobody to send to — no recipients, or every owner filtered out — completes as soon as it starts.

Starting in a later request needs the database store: the in-memory store only lives for the current request, console command or queued job.

Every other facade method — lookups, listing, the per-campaign handle, settings() — is covered in The Campaigns facade.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/campaigns-for-laravel.md)
