---
title: "Recipients from contacts — Campaigns for Laravel | Roundly"
description: "Address campaigns from contacts-for-laravel records and HasContacts owners, with verified-only and contact-kind rules."
url: https://roundly-consulting.com/open-source/docs/campaigns-for-laravel/contacts
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)

# Recipients from contacts

Campaigns resolves recipients straight from contacts-for-laravel, so you can address a campaign from the contact records you already keep instead of copying email strings around. Give your model the HasContacts trait:

```php
use Illuminate\Foundation\Auth\User as Authenticatable;
use RoundlyConsulting\Contacts\Concerns\HasContacts;

final class User extends Authenticatable
{
    use HasContacts;
}

$user->addEmail('ana@example.com', primary: true);
$user->addPhone('+12025550100', primary: true);
```

Then pass owners, contacts or iterables of them to ->to():

```php
use App\Models\User;
use RoundlyConsulting\Campaigns\Facades\Campaigns;
use RoundlyConsulting\Contacts\Enums\ContactType;

Campaigns::create('Spring sale', '<p>The spring sale starts today.</p>')
    ->onlyVerified()                        // skip owners/contacts without a verified contact
    ->viaContactType(ContactType::Email)    // which contact kind to resolve (email, phone, …)
    ->to($user)                             // HasContacts owner -> its primary email
    ->to($contact)                          // a Contact record -> its value
    ->to(User::query()->where('newsletter', true)->get()) // an iterable of owners
    ->dispatch();
```

## How recipients are resolved

- An owner resolves to its contact of the send kind — the primary one first, otherwise the first in order.
- A Contact record resolves to its own value; contacts with an empty value are skipped.
- The display name is the owner’s name attribute, then the contact’s name, then its label, then the address itself.
- Owners with no matching contact — or, under onlyVerified(), no verified one — are skipped silently, never fatal.
- An owner passed twice — say $user and again inside a collection — still gets one message: its address is already on the campaign.
- Resolution is read-only: Campaigns never writes to your contacts.

## Set the rules before to()

Recipients are resolved the moment you call ->to(), so onlyVerified() and viaContactType() only affect the to() calls that come after them. Without them, the OnlyVerifiedRecipients and DefaultRecipientContactType options apply (config: recipients.only-verified and recipients.contact-type). onlyVerified(false) turns verification off for one campaign even when the default is on.

## Phone numbers and SMS

viaContactType(ContactType::Phone) — or the plain string phone — resolves phone contacts instead of emails. Pair it with SendCampaignNotification or your own job to deliver over SMS:

```php
Campaigns::create('Delivery update', 'Your parcel is on its way.')
    ->viaContactType('phone')    // a ContactType value works as a plain string too
    ->to($customers)             // each owner resolves to its primary phone number
    ->dispatch();
```

A string that isn’t a ContactType value (email, phone, address, url, social, custom) throws a ValueError. Plain strings and CampaignRecipient objects keep working unchanged alongside contacts.

## 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)
