bentonow/bento-laravel-sdk

Laravel SDK for Bento

Maintainers

Package info

github.com/bentonow/bento-laravel-sdk

pkg:composer/bentonow/bento-laravel-sdk

Statistics

Installs: 37 627

Dependents: 1

Suggesters: 0

Stars: 19

Open Issues: 4

v1.3.2 2025-10-02 21:59 UTC

This package is auto-updated.

Last update: 2026-03-17 06:00:17 UTC


README

Tip

Need help? Join our Discord or email jesse@bentonow.com for personalized support.

The Bento Laravel SDK makes it quick and easy to send emails and track events in your Laravel applications. We provide powerful and customizable APIs that can be used out-of-the-box to manage subscribers, track events, and send transactional emails. We also expose low-level APIs so that you can build fully custom experiences.

Get started with our 📚 integration guides, or 📘 browse the SDK reference.

🐶 Battle-tested by High Performance SQLite (a Bento customer)!

❤️ Thank you @aarondfrancis for your contribution.

❤️ Thank you @ziptied for your contribution.

Tests

Table of contents

Features

  • Laravel Mail Integration: Seamlessly integrate with Laravel's mail system to send transactional emails via Bento.
  • Event Tracking: Easily track custom events and user behavior in your Laravel application.
  • Subscriber Management: Import and manage subscribers directly from your Laravel app.
  • API Access: Full access to Bento's REST API for advanced operations.
  • Laravel-friendly: Designed to work smoothly with Laravel's conventions and best practices.

Requirements

  • PHP 8.2+ (8.1 supported but untested)
  • Laravel 10.0+
  • Bento API Keys

Getting started

Installation

Install the package via Composer:

composer require bentonow/bento-laravel-sdk

Configuration (Prompt-Based)

After installing, run the install command to set up your environment interactively:

php artisan bento:install

You will be prompted for:

  • Your Bento Publishable Key
  • Your Bento Secret Key
  • Your Bento Site UUID
  • Whether you want to enable Bento for transactional emails
  • The author email for transactional mail (if transactional emails are enabled)
  • Whether you want to send a test email after configuration
  • Whether you want to automatically update your .env file

If you decline automatic .env modification, the command will display the required environment variables for you to copy and add manually. You will also see links to the Bento Laravel documentation and the Bento app.

Note: The install command uses Laravel Prompts for a modern, interactive setup experience. This requires Laravel 10+ and PHP 8.1+.

Manual Configuration (Advanced)

If you prefer, you can manually add the following to your .env file:

BENTO_PUBLISHABLE_KEY="your-publishable-key"
BENTO_SECRET_KEY="your-secret-key"
BENTO_SITE_UUID="your-site-uuid"
MAIL_MAILER=bento
MAIL_FROM_ADDRESS="author@example.com"

Testing Your Configuration

You can verify your transactional email configuration by running:

php artisan bento:test

This command will:

  • Verify that Bento is configured as your default mailer
  • Send a test email to your configured MAIL_FROM_ADDRESS
  • Provide immediate feedback on the success or failure of the test

Note: The test command requires Bento to be configured as your default mailer (MAIL_MAILER=bento) and a valid MAIL_FROM_ADDRESS to be set.

Modules

Event Tracking

Track custom events in your application:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\EventData;

$data = collect([
  new EventData(
    type: '$completed_onboarding',
    email: "user@example.com",
    fields: [
      "first_name" => "John",
      "last_name" => "Doe"
    ]
  )
]);

return Bento::trackEvent($data)->json();

Subscriber Management

Import subscribers into your Bento account:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\ImportSubscribersData;

$data = collect([
  new ImportSubscribersData(
    email: "user@example.com",
    first_name: "John",
    last_name: "Doe",
    tags: ["lead", "mql"],
    removeTags: ["customers"],
    fields: ["role" => "ceo"]
  ),
]);

return Bento::importSubscribers($data)->json();

Find Subscriber

Search your site for a subscriber:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::findSubscriber("test@example.com")->json();

Create Subscriber

Creates a subscriber in your account and queues them for indexing:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\CreateSubscriberData;

$data = new CreateSubscriberData(email: "test@example.com");

return Bento::createSubscriber($data)->json();

Run Command

Execute a command and change a subscriber's data:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\CommandData;
use Bentonow\BentoLaravel\Enums\Command;

$data = collect([
  new CommandData(Command::REMOVE_TAG, "test@gmail.com", "test")
]);

return Bento::subscriberCommand($data)->json();

Get Tags

Returns a list of tags in your account:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getTags()->json();

Create Tag

Creates a custom tag in your account:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\CreateTagData;

$data = new CreateTagData(name: "example tag");

return Bento::createTag($data)->json();

Get Fields

The field model is a simple named key value pair, think of it as a form field:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getFields()->json();

Create Field

Creates a custom field in your account:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\CreateFieldData;

$data = new CreateFieldData(key: "last_name");

return Bento::createField($data)->json();

Get Broadcasts

Returns a list of broadcasts in your account:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getBroadcasts()->json();

Create Broadcasts

Create new broadcasts to be sent:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\CreateBroadcastData;
use Bentonow\BentoLaravel\DataTransferObjects\ContactData;
use Bentonow\BentoLaravel\Enums\BroadcastType;

$data = Collect([
  new CreateBroadcastData(
    name: "Campaign #1 Example",
    subject: "Hello world Plain Text",
    content: "<p>Hi {{ visitor.first_name }}</p>",
    type: BroadcastType::PLAIN,
    from: new ContactData(
      name: "John Doe",
      emailAddress: "example@example.com"
    ),
    inclusive_tags: "lead,mql",
    exclusive_tags: "customers",
    segment_id: "segment_123456789",
    batch_size_per_hour: 1500
  ),
]);

return Bento::createBroadcast($data)->json();

Get Site Stats

Returns a list of site stats:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getSiteStats()->json();

Get Segment Stats

Returns a list of a segments stats:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\SegmentStatsData;

$data = new SegmentStatsData(segment_id: "123");

return Bento::getSegmentStats($data)->json();

Get Report Stats

Returns an object containing data for a specific report:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\ReportStatsData;

$data = new ReportStatsData(report_id: "456");

return Bento::getReportStats($data)->json();

Search Blacklists

Validates the IP or domain name with industry email reputation services to check for delivery issues:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\BlacklistStatusData;

$data = new BlacklistStatusData(domain: null, ipAddress: "1.1.1.1");
return Bento::getBlacklistStatus($data)->json();

Validate Email

Validates the email address using the provided information to infer its validity:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\ValidateEmailData;

$data = new ValidateEmailData(
  emailAddress: "test@example.com",
  fullName: "John Snow",
  userAgent: null,
  ipAddress: null
);

return Bento::validateEmail($data)->json();

Moderate Content

An opinionated Content moderation:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\ContentModerationData;

$data = new ContentModerationData("Its just so fluffy!");
return Bento::getContentModeration($data)->json();

Guess Gender

Guess a subscriber's gender using their first and last name. Best for US users; based on US Census Data:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\GenderData;

$data = new GenderData("John Doe");
return Bento::getGender($data)->json();

Geolocate Ip Address

This endpoint attempts to geolocate the provided IP address:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\GeoLocateIpData;

$data = new GeoLocateIpData("1.1.1.1");
return Bento::geoLocateIp($data)->json();

Get Email Template

Retrieve a single email template by ID:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getEmailTemplate(123)->json();

Update Email Template

Update an email template's subject and/or HTML content. Only the fields you provide will be updated:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\UpdateEmailTemplateData;

$data = new UpdateEmailTemplateData(
  id: 123,
  subject: "Updated Subject",
  html: "<p>Updated content</p>"
);

return Bento::updateEmailTemplate($data)->json();

Get Sequences

Returns a list of sequences in your account. Supports pagination:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getSequences()->json();

// With pagination
return Bento::getSequences(page: 2)->json();

Create Sequence Email

Create a new email template within a sequence:

use Bentonow\BentoLaravel\Facades\Bento;
use Bentonow\BentoLaravel\DataTransferObjects\CreateSequenceEmailData;

$data = new CreateSequenceEmailData(
  sequenceId: "123",
  subject: "Day 1: Welcome!",
  html: "<p>Thanks for signing up</p>",
  delayInterval: "days",
  delayIntervalCount: 1
);

return Bento::createSequenceEmail($data)->json();

Get Workflows

Returns a list of workflows in your account. Supports pagination:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getWorkflows()->json();

// With pagination
return Bento::getWorkflows(page: 2)->json();

Get Form Responses

Get all responses for a form by its identifier:

use Bentonow\BentoLaravel\Facades\Bento;

return Bento::getFormResponses("my-form-id")->json();

Tag Subscriber

Tag a subscriber with automation triggers:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::tagSubscriber("user@example.com", "vip");

Remove Tag

Remove a tag from a subscriber with automation triggers:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::removeTag("user@example.com", "vip");

Add Subscriber

Add a subscriber with automation triggers:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::addSubscriber("user@example.com", [
  "first_name" => "John",
  "last_name" => "Doe"
]);

Remove Subscriber

Unsubscribe a subscriber with automation triggers:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::removeSubscriber("user@example.com");

Update Fields

Update custom fields on a subscriber with automation triggers:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::updateFields("user@example.com", [
  "plan" => "pro",
  "company" => "Acme Inc"
]);

Track Purchase

Track a purchase for LTV calculation with automation triggers. Amounts should be in cents:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::trackPurchase("user@example.com", [
  "unique" => ["key" => "order-123"],
  "value" => ["amount" => 9999, "currency" => "USD"],
  "cart" => [
    ["product_id" => "sku-1", "quantity" => 1, "price" => 9999]
  ]
]);

Track

Track a custom event with automation triggers:

use Bentonow\BentoLaravel\Facades\Bento;

Bento::track(
  "user@example.com",
  '$completed_onboarding',
  fields: ["first_name" => "John"],
  details: ["step" => "final"]
);

Upsert Subscriber

Create or update a subscriber and return the record. Throws a RuntimeException if the import fails:

use Bentonow\BentoLaravel\Facades\Bento;

$subscriber = Bento::upsertSubscriber(
  email: "user@example.com",
  firstName: "John",
  lastName: "Doe",
  tags: ["lead", "website"],
  fields: ["role" => "ceo"]
);

return $subscriber->json();

Note: If the import step fails (e.g. invalid data), a RuntimeException is thrown instead of returning a partial response. Wrap the call in a try/catch if you need to handle failures gracefully:

try {
    $subscriber = Bento::upsertSubscriber(email: "user@example.com");
} catch (\RuntimeException $e) {
    // Handle the failure
    Log::warning($e->getMessage());
}

Things to Know

  1. The SDK integrates seamlessly with Laravel's mail system for sending transactional emails.
  2. For event tracking and data importing, use the BentoConnector class.
  3. All API requests are made using strongly-typed request classes for better type safety.
  4. The SDK supports Laravel's environment-based configuration for easy setup across different environments.
  5. For signed emails with return urls, please assign the bento.signature middleware or the BentoSignatureExclusion::class. This must be before the signed middleware to remove all utm and tracking url params.
  6. Bento does not support no-reply sender addresses for transactional emails. You MUST use an author you have configured as your sender address.
  7. For more advanced usage, refer to the Bento API Documentation.

Contributing

We welcome contributions! Please see our contributing guidelines for details on how to submit pull requests, report issues, and suggest improvements.

License

The Bento SDK for Laravel is available as open source under the terms of the MIT License.