Bento Laravel Guide

This guide will help you implement Bento into your Laravel applications, regardless of your development experience.

Reference

Getting Started
1
Package Installation

Installation

Install the Bento Laravel SDK in your project:

Using Composer

composer require bentonow/bento-laravel-sdk
2
Client Configuration

Basic Setup

To initialize the Bento client, you'll need your Site UUID, Publishable Key, and Secret Key from your Bento account. You can find your keys in your Bento Team. To see your keys click Your Private API Keys Button and if do you do not see a Publishable key and Secret Key, click on Generate Key to create a set.

Publish the configuration

php artisan vendor:publish --tag="bentonow

Then configure your .env file

BENTO_PUBLISHABLE_KEY=your_publishable_key
BENTO_SECRET_KEY=your_secret_key
BENTO_SITE_UUID=your_site_uuid

Ready use the Bento facade

use Bentonow\BentoLaravel\Facades\Bento;
Beginner Guide

Tracking Your First Event

Events represent specific actions users take within your application. Tracking these actions provides valuable insights into user behavior patterns and engagement.

Streamlined Subscriber Management

We recommend using Events as the preferred method to add subscribers, as they simultaneously initiate workflows and automations in a single operation.

Powerful Data Enrichment

Events excel at capturing contextual information alongside user actions. This can be used in emails via liquid tags or in segmentation. For instance, when recording a purchase event, you can include detailed transaction information such as:

DetailLiquid tag
Product details
Purchase amount
Transaction ID
Payment method

Practical Example

When a customer completes a purchase, you can track this as an event while including all relevant purchase details. This approach enables you to:

  • Trigger specific post-purchase workflows
  • Launch targeted follow-up automations
  • Track lifetime value (LTV) metrics
  • Create personalized communications based on purchase history

Track a simple page view

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $event = new EventData(
        type: '$pageView',
        email: '[email protected]',
        details: [
            'url' => '/home',
            'title' => 'Home Page',
        ]
    );

    Bento::trackEvent(collect([$event]));

Track a form submission

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $event = new EventData(
        type: '$formSubmitted',
        email: '[email protected]',
        details: [
            'formName' => 'Newsletter Signup',
            'source' => 'Homepage',
        ]
    );

    Bento::trackEvent(collect([$event]));

Managing Subscribers

If you need to manage subscribers directly there are a set of convenience methods available to you. Add, update, and unsubscribe subscribers with these simple methods. Currently, you cannot remove subscribers via the API, but you can remove them from the dashboard People > All Users.

Create a new subscriber

createSubscriber()
/v1/batch/subscribers
    use Bentonow\BentoLaravel\DataTransferObjects\CreateSubscriberData;
    use Bentonow\BentoLaravel\Facades\Bento;

    $subscriber = new CreateSubscriberData(
      email: '[email protected]'
    );

    Bento::createSubscriber($subscriber);

Adding Individual Subscribers

Please note, while these methods make it easy to manage a subscriber, the Bento recommended way to add a subscriber is via an event. This allows you to kick off sequences and automations, while also recording the "event" at the same time (1 API call).

Adding Multiple Subscribers

Importing or modifying multiple subscribers should be handled via the bulk methods, instead of looping over these calls multiple times.

Common Use Cases

Here are some common scenarios with ready-to-use code:

Tracking a user login "Event"

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $event = new EventData(
      type: '$login',
      email: '[email protected]',
      details: [
        'method' => 'password',
        'device' => 'mobile',
      ]
    );

    Bento::trackEvent(collect([$event]));
Intermediate Guide

Custom Fields and Tags

Bento allows you to store custom data about your users through fields and segment them with tags:

Create a new custom field definition

createField()
/v1/fetch/fields
    use Bentonow\BentoLaravel\DataTransferObjects\CreateFieldData;
    use Bentonow\BentoLaravel\Facades\Bento;

    $field = new CreateFieldData(
      key: 'membershipLevel'
    );

    Bento::createField($field);

Using Custom Fields & Tags

While custom fields and tags can be used to segment subscribers, most Bento users find that namespaced tags provide a more effective and easier-to-maintain solution for most segmentation use cases.

Namespaced Tags

Namespaced tags follow this format: namespace:detail For example, if you offer three subscription plans, you could create these tags:

  • subscription:basic
  • subscription:pro
  • subscription:enterprise

We recommend applying these tags either through an automated flow or via bulk updates.

Fields

Fields are perfect for storing information about your subscribers, such as their language, timezone, or other relevant details. By using fields, you can easily segment subscribers based on their specific needs and preferences, allowing you to tailor your marketing efforts and messaging to each group.

The primary difference between fields and namespaced tags is that fields are not limited to a specific detail and do not need to be predefined. You can store any type of data in a field, including strings, numbers, or even objects. This flexibility makes fields a powerful tool for storing data.

Best Practices

For optimal organization, consider using tags for segmentation while storing more detailed user information in custom fields. Many successful implementations use a strategic combination of both approaches.

Tracking Purchase Events

When recording purchase events, you must include a unique: key as part of the tracking data. This requirement prevents duplicate transactions from being recorded in your analytics.

Most users find it beneficial to use their internal cart or order number as the unique: key. This approach simplifies future lookups and maintains consistency across your systems. The unique: key value you provide is accessible through liquid tags when creating custom email templates, allowing for personalized transactional messaging based on specific purchase details.

Tracking purchases is a great way to monitor customer lifetime value (LTV) and identify recurring customers. Bento reports on the LTV of each subscriber, allowing you to identify high-value customers and tailor your marketing efforts accordingly.

Track a purchase event to monitor customer lifetime value

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $event = new EventData(
        type: '$purchase',
        email: '[email protected]',
        details: [
            'unique' => [
                'key' => 'order-123' // Unique order identifier
            ],
            'value' => [
                'amount' => 9999, // Amount in cents
                'currency' => 'USD'
            ],
            'cart' => [
                'items' => [
                    [
                        'product_id' => 'prod-456',
                        'product_name' => 'Premium Widget',
                        'product_price' => 9999,
                        'quantity' => 1,
                        'product_sku' => 'SKU-456',
                    ]
                ]
            ]
        ]
    );

    Bento::trackEvent(collect([$event]));
Advanced Guide

Batch Operations

For efficiency, we suggest using batch operations when integrating with Bento. These methods allow for single or bulk operations on subscribers and events, improving the performance and scalability of your integration. They also cover more than 80% of the API use cases for most customers.

Import multiple subscribers at once

importSubscribers()
/v1/batch/subscribers
    use Bentonow\BentoLaravel\DataTransferObjects\ImportSubscribersData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $subscribers = collect([
        new ImportSubscribersData(
            email: '[email protected]',
            firstName: 'Alice',
            lastName: null,
            tags: null,
            removeTags: null,
            fields: ['company' => 'Acme Inc']
        ),
        new ImportSubscribersData(
            email: '[email protected]',
            firstName: 'Bob',
            lastName: null,
            tags: null,
            removeTags: null,
            fields: ['company' => 'Beta Corp']
        ),
        // ... up to 1,000 subscribers
    ]);

    Bento::importSubscribers($subscribers);

Import multiple events at once

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $events = collect([
        new EventData(
            type: '$login',
            email: '[email protected]',
            fields: ['date' => '2023-01-01']
        ),
        new EventData(
            type: '$purchase',
            email: '[email protected]',
            details: [
                'unique' => ['key' => 'order-123'],
                'value' => ['currency' => 'USD', 'amount' => 9999]
            ]
        ),
        // ... up to 1,000 events
    ]);

    Bento::trackEvent($events);

Transactional Emails

Bento allows you to send personalized transactional emails for time-sensitive, direct communications. These emails serve specific functional purposes rather than marketing objectives.

Ideal Transactional Email Use Cases

  • User onboarding (confirmation etc)
  • Password reset notifications
  • Sign-in verification links
  • Order confirmations and details
  • Account notifications

From Address Requirements

The sender address used in your transactional emails must be configured as an Author email within your Bento settings. Please note that generic addresses such as "[email protected]" or similar non-personal addresses are not currently supported.

Important Distinction

Transactional emails are designed for essential communications that facilitate specific user actions or provide critical information.

Send a transactional email

Mail Transport
/v1/batch/emails
    // Laravel provides a native way to send emails through Bento
    // First, configure your .env file to use Bento as a mail driver:
    // MAIL_MAILER=bento

    // Then, use Laravel's built-in Mail facade:
    use Illuminate\Support\Facades\Mail;

    // You can use a Laravel Mailable class:
    Mail::to('[email protected]')
        ->from('Your Name <[email protected]>')
        ->send(new OrderShippedMailable($order));

    // Example Mailable class:

    class OrderShippedMailable extends Mailable
    {
        public $order;

        public function __construct($order)
        {
            $this->order = $order;
        }

        public function build()
        {
            return $this->subject('Your order #' . $this->order->id . ' has shipped!')
                        ->view('emails.orders.shipped');
        }
    }

Subscriber Updates

Many organizations joining Bento already have an established subscriber base that requires bulk updates over time. These updates commonly include setting field data and managing tags across multiple subscribers. We firmly believe that these methods are the best way to manage a single or multiple subscribers, and we recommend using them for all subscriber updates.

Choosing the Right Update Method:

The SDK offers multiple approaches for creating subscribers in Bento, each suited to different scenarios.

Preferred Method: Events

The recommended way to create subscribers is via events in response to user activity. This approach activates automations, workflows, and can contain data enrichment.

Create a subscriber when they sign up

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $event = new EventData(
      type: '$subscribe',
      email: '[email protected]',
      fields: [
        'firstName' => 'Jane',
        'lastName' => 'Doe',
        'signupSource' => 'website'
      ]
    );

    Bento::trackEvent(collect([$event]));

Alternative Methods

For scenarios where you need to create subscribers independently of user actions:

1
Single Subscriber Creation

Use this method when you need to quickly create a single subscriber with minimal data:

Create a single subscriber (email only)

createSubscriber()
/v1/fetch/subscribers
    use Bentonow\BentoLaravel\DataTransferObjects\CreateSubscriberData;
    use Bentonow\BentoLaravel\Facades\Bento;

    $subscriber = new CreateSubscriberData(
      email: '[email protected]'
    );

    Bento::createSubscriber($subscriber);
2
Multiple Or Enriched Subscriber Creation

For creating multiple subscribers or including additional fields:

Import multiple subscribers

importSubscribers()
/v1/batch/subscribers
    use Bentonow\BentoLaravel\DataTransferObjects\ImportSubscribersData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $subscribers = collect([
      new ImportSubscribersData(
        email: '[email protected]',
        firstName: null,
        lastName: null,
        tags: null,
        removeTags: null,
        fields: [
          'membershipTier' => 'gold',
          'accountStatus' => 'active',
          'lastRenewalDate' => now()->toDateTimeString()
        ]
      ),
      new ImportSubscribersData(
        email: '[email protected]',
        firstName: null,
        lastName: null,
        tags: null,
        removeTags: null,
        fields: [
          'membershipTier' => 'silver',
          'accountStatus' => 'pending',
          'trialEndsAt' => now()->addDays(30)->toDateTimeString()
        ]
      )
    ]);

    Bento::importSubscribers($subscribers);

Best Practices for Batch Imports:

  • Though the API supports up to 1,000 subscribers per call, we recommend batches of 200-300 for optimal performance when dealing with extensive data.
  • Include all relevant custom fields in the initial import to minimize follow-up updates.
  • For very large imports (10,000+ subscribers), consider implementing a queue system with delay between batches.

Updating Subscribers

Depending on your requirements, several approaches are available for updating subscriber information.

Event-Based Updates (Preferred)

When updates occur in response to user actions, tracking events is the recommended approach:

Update subscriber when they update their profile

trackEvent()
/v1/batch/events
    use Bentonow\BentoLaravel\DataTransferObjects\EventData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $event = new EventData(
        type: '$subcription_change',
        email: '[email protected]',
        fields: [
            'subscriptionTier' => 'premium',
        ]
    );

    Bento::trackEvent(collect([$event]));

Alternative Update Methods

For updates outside of user-triggered actions:

1
Single Attribute Updates

For quickly updating a specific attribute on a single subscriber:

Add or update a single field

importSubscribers()
/v1/batch/subscribers
    use Bentonow\BentoLaravel\DataTransferObjects\ImportSubscribersData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $subscribers = collect([
      new ImportSubscribersData(
        email: '[email protected]',
        firstName: 'Jesse',
        lastName: 'Bento',
        tags: ['membership:premium'],
        removeTags: ['membership:silver'],
        fields: [
          'membershipTier' => 'premium',
          'accountStatus' => 'pending',
          'trialEndsAt' => now()->addDays(30)->toDateTimeString()
        ]
      )
    ]);

    Bento::importSubscribers($subscribers);
2
Batch Updates

For updating multiple subscribers or multiple fields at once, use the batch import method:

Update multiple subscribers

importSubscribers()
/v1/batch/subscribers
    use Bentonow\BentoLaravel\DataTransferObjects\ImportSubscribersData;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $subscribers = collect([
      new ImportSubscribersData(
        email: '[email protected]',
        firstName: null,
        lastName: null,
        tags: null,
        removeTags: null,
        fields: [
          'membershipTier' => 'gold',
          'accountStatus' => 'active',
          'lastRenewalDate' => now()->toDateTimeString()
        ]
      ),
      new ImportSubscribersData(
        email: '[email protected]',
        firstName: null,
        lastName: null,
        tags: null,
        removeTags: null,
        fields: [
          'membershipTier' => 'silver',
          'accountStatus' => 'pending',
          'trialEndsAt' => now()->addDays(30)->toDateTimeString()
        ]
      )
    ]);

    Bento::importSubscribers($subscribers);

Recommendations:

  • Even for single-subscriber updates, consider using the batch import method when multiple fields need updating.
  • The batch import performs an "upsert" operation – it creates subscribers that don't exist and updates those that do.
  • This approach provides the most flexibility as your use cases evolve, whether you need to add more changes or modify multiple users simultaneously.

Specialized Update Operations

For specific update scenarios, the SDK offers dedicated methods:

Change a subscribers email address

subscriberCommand()
/v1/fetch/commands
    use Bentonow\BentoLaravel\DataTransferObjects\CommandData;
    use Bentonow\BentoLaravel\Enums\Command;
    use Bentonow\BentoLaravel\Facades\Bento;
    use Illuminate\Support\Collection;

    $command = new CommandData(
      command: Command::CHANGE_EMAIL,
      email: '[email protected]',
      query: '[email protected]'
    );

    Bento::subscriberCommand(collect([$command]));

Utility Features

These features provide additional convenience utility for Bento users, to handle some of the common secondary use cases we commonly see, such as validation and blacklist checks.

Email validation

validateEmail()
/v1/experimental/validation
    use Bentonow\BentoLaravel\DataTransferObjects\ValidateEmailData;
    use Bentonow\BentoLaravel\Facades\Bento;

    $data = new ValidateEmailData(
      emailAddress: '[email protected]',
      fullName: null,
      userAgent: 'Mozilla/5.0...',
      ipAddress: '192.168.1.1'
    );

    $validationResult = Bento::validateEmail($data);
API Reference

Core API

  • Bento Facade - Main entry point for using the SDK (Bentonow\BentoLaravel\Facades\Bento)
  • Configuration - Set up through Laravel's config system (config/bentonow.php)
  • Service Provider - Automatically registered via Laravel's package discovery
  • Data Transfer Objects - Structured request data classes in Bentonow\BentoLaravel\DataTransferObjects
  • Laravel Mail Integration - Use the Bento transport with Laravel's Mail facade

Convenience Methods

Core API

Use CaseLaravel SDK Method
Add a new subscriber
Unsubscribe a subscriber
Update a data for an existing subscriber
Add a tag to a subscriber
Update subscriber fields
Track a custom event
Track a purchase event

Modules

Batch

Use CaseMethodAPI Reference
Import multiple subscribers Import Subscribers >>
Import multiple events Import Events >>
Send emails Send Emails >>

Commands

Use CaseMethodAPI Reference
Add a tag Subscriber Upsert >>
Remove a tag Subscriber Upsert >>
Add a field Subscriber Upsert >>
Remove a field Subscriber Upsert >>
Subscribe a user Subscriber Command >>
Unsubscribe a user Subscriber Command >>
Change email address Subscriber Command >>

Experimental

Use CaseMethodAPI Reference
Validate email address Validate Email >>
Predict gender from name Gender Guess >>
Get IP geolocation IP Geolocation >>
Check domain/IP blacklist Blacklist Check >>

Fields

Use CaseMethodAPI Reference
Get all fields Get Fields >>
Create a field Create Fields >>

Subscribers

Use CaseMethodAPI Reference
Find subscriber Find Subscriber >>
Create a subscriber Create Subscriber >>
Run commands Subscriber Commands >>

Tags

Use CaseMethodAPI Reference
Get all tags List Tags >>
Create a tag Create Tag >>
Troubleshooting

Common Errors

Not AuthorizedCheck your API keys and ensure they have appropriate permissions
Rate LimitedImplement backoff/retry logic for batch operations
Network ErrorsCheck internet connectivity and API endpoint availability
ExceptionsDouble check you are using a valid Author & the payload format.

Debugging Tips

1.Enable logErrors: true in your configuration for detailed error logging
2.Use try/catch blocks around API calls to handle errors gracefully
3.For batch operations, start with smaller batches to isolate issues
FAQ

Was this page helpful?