---
title: "Contacts for Laravel — docs | Roundly"
description: "Developer docs for Contacts for Laravel: typed polymorphic contacts, normalization, a primary per kind, verification, validation, events and vCard export."
url: https://roundly-consulting.com/open-source/docs/contacts-for-laravel
language: en
---

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

Open source

# Contacts for Laravel

Install

`composer require roundly-consulting/contacts-for-laravel`

Requires: PHP ^8.4 · Laravel ^12.0|^13.0

[GitHub](https://github.com/roundly-consulting/contacts-for-laravel) [Packagist](https://packagist.org/packages/roundly-consulting/contacts-for-laravel) [Donate (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Patreon](https://www.patreon.com/cw/roundly)

## Overview

Typed, validated, primary-aware contacts for any Laravel model. Attach emails, phones, addresses, URLs, social handles and your own custom kinds to a user, a company, an order or anything else — all in one polymorphic contacts table, normalized on the way in, with one primary per kind, ordering, a channel-agnostic verification flow, events, a fluent facade and native vCard 3.0 export. MIT-licensed and dependency-light: Laravel plus a few small Roundly foundation packages — no third-party libraries.

### What you get

#### Typed, normalized contacts

Emails, phones, addresses, URLs, social handles and custom kinds on any model — lower-cased, E.164-ish and scheme-complete on the way in.

#### One primary per kind

The first contact of a kind becomes primary automatically, promoting another demotes the old one, and when the primary leaves, the next takes over.

#### Verification without sending

Numeric codes or random tokens, stored only as a hash with an expiry and a wrong-guess limit. An event hands you the plaintext — you deliver it your way.

#### Reusable validation

ValidContactValue, ContactType::rules() and ready contacts.\* array rules drop straight into your FormRequests.

#### vCard 3.0 & notification routing

Export an owner’s contacts as a valid vCard, and route mail, Vonage and Twilio notifications to its primary contacts.

#### Addresses & relationships

Structured postal addresses on a contact and a typed relationship graph — works at, spouse of — with invitations.

#### Built for tests

A recording Contacts::fake() that writes nothing — injected managers included — plus factory states and Pest matchers.

### Documentation

#### [Installation](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/installation.md)

Install via Composer, publish the contacts migrations and the two companion migrations, then optionally publish config and translations.

#### [Configuration](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/configuration.md)

Every config key and its default — model, table, key type, auto-primary, country code, verification, custom kinds and relationship kinds.

#### [Database schema & key types](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/database-schema.md)

The contacts table column by column, its indexes, soft deletes, and how key\_type types owner\_id for UUID or ULID owner models.

#### [The HasContacts trait](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/has-contacts.md)

Add HasContacts to any model for one-line addEmail/addPhone helpers, primary lookups, ordered per-kind collections and the contacts relation.

#### [The Contacts facade](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/facade.md)

Contacts::for($owner) for an owner’s contact book, verification() for the token flow, flat calls for one contact — plus the builder and ContactData.

#### [DI and actions](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/without-facade.md)

Inject ContactsManager for the facade’s API without static calls, or run one of the eight single-purpose contact actions directly.

#### [Contact kinds & normalization](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/contact-kinds.md)

The six built-in ContactType kinds, how each value is normalized and validated, their labels and icons, and the enum helpers for selects.

#### [Custom kinds](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/custom-kinds.md)

Register kinds such as whatsapp in config with their own label, icon and validation rules — each keeps its own primary and query scope.

#### [Primary contacts & ordering](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/primary-contacts.md)

One primary per owner and kind — auto-assigned, swapped in a transaction, handed to the next contact when it leaves — plus per-kind ordering.

#### [Syncing contacts](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/syncing.md)

Reconcile an owner’s contacts of one kind to an exact list — update matches in place, create new ones, delete the rest, order by input.

#### [Verification](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/verification.md)

Issue a code or token stored only as a hash with an expiry and an attempt limit, deliver it from an event, then confirm it to verify the contact.

#### [Validation](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/validation.md)

Reuse the package’s validation in your forms: the ValidContactValue rule, ContactType::rules() and ready rules for repeatable contact arrays.

#### [Query scopes](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/query-scopes.md)

Composable Contact scopes — by owner, category, kind, primary, verification status, free-text search and position order.

#### [Events](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/events.md)

Six events for adds, updates, deletes, verification requests, verification and primary changes — react without forking.

#### [Notification routing](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/notifications.md)

Opt a model into routing mail, Vonage and Twilio notifications to its primary email and phone with RoutesNotificationsViaContacts.

#### [vCard export](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/vcard.md)

Export an owner’s contacts or a single contact as a valid vCard 3.0 card that Apple, Google and other address books read.

#### [Structured addresses](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/addresses.md)

Give a contact validated billing, home or work addresses via addresses-for-laravel, with a one-line render that falls back to the value.

#### [Affiliations & relationships](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/relationships.md)

Link contacts to each other and to owners — works at, spouse of — with invitations, expiry and an optional allow-list of relationship kinds.

#### [Exceptions](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/exceptions.md)

Every exception the package throws, when it is thrown, and how to catch them all through the ContactException base class.

#### [Testing](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/testing.md)

Swap in the recording Contacts::fake() and assert every write, build fixtures with per-kind factory states, and assert owners with Pest matchers.

#### [Requirements](https://roundly-consulting.com/open-source/docs/contacts-for-laravel/requirements.md)

PHP 8.4+, Laravel 12 or 13, and five small Roundly foundation packages that Composer installs for you.

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