> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendkit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel

> Integrate SendKit with Laravel using the official package.

<CardGroup cols={2}>
  <Card title="Source Code" icon="github" href="https://github.com/sendkitdev/sendkit-laravel">
    View on GitHub
  </Card>

  <Card title="Package" icon="box" href="https://packagist.org/packages/sendkit/sendkit-laravel">
    View on Packagist
  </Card>
</CardGroup>

## Install

```bash theme={null}
composer require sendkit/sendkit-laravel
```

## Configure

Add your API key to your `.env` file:

```bash .env theme={null}
SENDKIT_API_KEY=sk_your_api_key
```

## Send email

### Using the Laravel Mail driver

SendKit integrates with Laravel's built-in Mail system. Just set the mailer in your `.env`:

```bash .env theme={null}
MAIL_MAILER=sendkit
```

That's it. Send emails using Laravel's standard `Mail` facade as usual:

```php theme={null}
use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;

Mail::to('recipient@example.com')->send(new WelcomeEmail());
```

### Using the SendKit facade

If you need more control, you can use the SendKit facade directly:

```php theme={null}
use SendKit\Laravel\Facades\SendKit;

$response = SendKit::emails()->send([
    'from' => 'Your Name <you@yourdomain.com>',
    'to' => 'recipient@example.com',
    'subject' => 'Hello from SendKit',
    'html' => '<h1>Welcome!</h1><p>Your first email with SendKit.</p>',
]);

echo $response['id'];
```

## Validate email

Validate an email address before sending. Each validation costs credits.

```php theme={null}
use SendKit\Laravel\Facades\SendKit;

$result = SendKit::validateEmail('recipient@example.com');

if ($result['should_block']) {
    // Email should not be used
    echo $result['block_reason'];
}

echo $result['is_valid'];           // "HIGH" or "LOW"
echo $result['evaluations'];        // detailed checks
```

The `evaluations` array contains:

| Key                | Description                                      |
| ------------------ | ------------------------------------------------ |
| `has_valid_syntax` | Whether the email has valid syntax               |
| `has_valid_dns`    | Whether the domain has valid DNS records         |
| `mailbox_exists`   | Whether the mailbox exists                       |
| `is_role_address`  | Whether it's a role address (e.g. info@, admin@) |
| `is_disposable`    | Whether it's a disposable email                  |
| `is_random_input`  | Whether it appears to be random input            |

## Contacts

### Create or update a contact

Create a new contact or update an existing one if the email already exists (upsert).

```php theme={null}
use SendKit\Laravel\Facades\SendKit;

$contact = SendKit::contacts()->create([
    'email' => 'john@example.com',
    'first_name' => 'John',
    'last_name' => 'Doe',
    'list_ids' => ['list-uuid-1', 'list-uuid-2'],
    'properties' => ['COMPANY' => 'Acme'],
]);

echo $contact['id'];
```

### List contacts

Retrieve a paginated list of contacts.

```php theme={null}
$contacts = SendKit::contacts()->list();

// With pagination
$contacts = SendKit::contacts()->list(['page' => 2]);

echo $contacts['meta']['total'];    // total contacts
```

### Get a contact

```php theme={null}
$contact = SendKit::contacts()->get('contact-uuid');

echo $contact['email'];
echo $contact['properties']['COMPANY'];
```

### Update a contact

```php theme={null}
$contact = SendKit::contacts()->update('contact-uuid', [
    'first_name' => 'Johnny',
    'unsubscribed' => true,
]);
```

### Delete a contact

```php theme={null}
SendKit::contacts()->delete('contact-uuid');
```

### Add a contact to lists

```php theme={null}
$contact = SendKit::contacts()->addToLists('contact-uuid', [
    'list-uuid-1',
    'list-uuid-2',
]);
```

### List a contact's lists

```php theme={null}
$lists = SendKit::contacts()->listLists('contact-uuid');

// With pagination
$lists = SendKit::contacts()->listLists('contact-uuid', ['page' => 2]);
```

### Remove a contact from a list

```php theme={null}
SendKit::contacts()->removeFromList('contact-uuid', 'list-uuid');
```

## Contact properties

Contact properties let you define custom fields for your contacts.

### Create a property

```php theme={null}
use SendKit\Laravel\Facades\SendKit;

$property = SendKit::contactProperties()->create([
    'key' => 'company',
    'type' => 'string',           // "string", "number", or "date"
    'fallback_value' => 'N/A',    // optional
]);

echo $property['id'];
```

### List properties

```php theme={null}
$properties = SendKit::contactProperties()->list();

// With pagination
$properties = SendKit::contactProperties()->list(['page' => 2]);
```

### Update a property

```php theme={null}
$property = SendKit::contactProperties()->update('property-uuid', [
    'key' => 'organization',
    'fallback_value' => 'Unknown',
]);
```

### Delete a property

```php theme={null}
SendKit::contactProperties()->delete('property-uuid');
```

<Note>
  A `SendKitException` with status `409` is thrown if the property is used in segment filters.
</Note>

## Webhooks

The package automatically registers a `POST /webhook/sendkit` route in your application — no extra setup needed. When SendKit sends a webhook to this endpoint, the package verifies the signature and dispatches a Laravel event you can listen to.

### Add your webhook secret

To verify that incoming webhooks are actually from SendKit, add your webhook secret to `.env`:

```bash .env theme={null}
SENDKIT_WEBHOOK_SECRET=your-webhook-secret
```

You can find your webhook secret in the [SendKit dashboard](https://app.sendkit.dev). When a secret is configured, every incoming request is verified using HMAC-SHA256. If the signature doesn't match, the request is rejected with a `403` response.

<Note>
  If no secret is configured, signature verification is skipped. We strongly recommend always setting a secret in production.
</Note>

### Customizing the webhook path

By default the webhook listens at `/webhook/sendkit`. You can change this with an environment variable:

```bash .env theme={null}
SENDKIT_WEBHOOK_PATH=api/webhooks/sendkit
```

This will register the route at `POST /api/webhooks/sendkit` instead. Make sure to update the webhook URL in your SendKit dashboard to match.

### Listening for events

When a webhook is received, the package dispatches a Laravel event based on the event type. You can listen for these events anywhere you normally would — in a listener, a service provider, or an `EventServiceProvider`:

```php theme={null}
use SendKit\Laravel\Events\EmailDelivered;
use Illuminate\Support\Facades\Event;

Event::listen(EmailDelivered::class, function ($event) {
    $emailId = $event->payload['email_id'];

    // Handle the delivered email
});
```

Every event has a `payload` property with the webhook data sent by SendKit.

### Available events

| Event class            | Webhook type             | Triggered when                       |
| ---------------------- | ------------------------ | ------------------------------------ |
| `EmailSent`            | `email.sent`             | Email accepted for delivery          |
| `EmailDelivered`       | `email.delivered`        | Email delivered to recipient         |
| `EmailBounced`         | `email.bounced`          | Email bounced                        |
| `EmailComplained`      | `email.complained`       | Recipient marked as spam             |
| `EmailOpened`          | `email.opened`           | Recipient opened the email           |
| `EmailClicked`         | `email.clicked`          | Recipient clicked a link             |
| `EmailFailed`          | `email.failed`           | Email failed to send                 |
| `EmailDeliveryDelayed` | `email.delivery_delayed` | Delivery is taking longer than usual |
| `EmailRejected`        | `email.rejected`         | Email was rejected                   |
| `ContactCreated`       | `contact.created`        | Contact was created                  |
| `ContactUpdated`       | `contact.updated`        | Contact was updated                  |
| `ContactDeleted`       | `contact.deleted`        | Contact was deleted                  |

All event classes are in the `SendKit\Laravel\Events` namespace.

### Advanced configuration

For full control over the webhook configuration, publish the config file:

```bash theme={null}
php artisan vendor:publish --tag=sendkit-config
```

This creates a `config/sendkit.php` file where you can customize the webhook path, secret, and other options.
