import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator
} from '@/components/docs/ui/breadcrumb'


export const exampleFile = 'node-guide-examples'
# Bento Node.js Guide

This guide covers installing the Bento Node.js SDK, configuring the client, and the main operations: tracking events, managing subscribers, and sending transactional emails from your Node.js application.


  
  
  
  


### Reference

  # [API Reference](#api-reference)
  # [Troubleshooting](#troubleshooting)
  # [FAQ](#faq)


## Getting Started


**1. Package Installation**


  ## Installation

  Install the Bento Node SDK in your project:


**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](https://app.bentonow.com/account/teams). To see your keys, click
    `Your Private API Keys`. If you do not see a Publishable key and Secret Key, click `Generate Key` to
    create a set.

    

    You can also configure a custom request timeout via `clientOptions`:

    

    
> Requests default to a 30-second timeout. You can customize this via `clientOptions.timeout` (in milliseconds).

  


## Beginner Guide


## Tracking Your First Event

Events record actions users take in your application, like signing up or making a purchase.

#### Adding subscribers via events
Events are the preferred way to add subscribers. One call records the event and kicks off any workflows and
automations tied to it.

#### Enriching events with data
Events can carry contextual data alongside the action itself. This can be used in emails via
[liquid tags](/docs/liquid_guide) or in segmentation. For instance, when recording a purchase event, you can include detailed
transaction information such as:

| Detail                                                   | Liquid 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


## 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`.


  <summary>
    
  </summary>
  <content>

    
    
  </content>


#### 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](/docs/examples/nodejs#subscriber-updates),
instead of looping over these calls multiple times.


## Common Use Cases

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

  <summary>
    
  </summary>
  <content>
    
    
  </content>
  


## Intermediate Guide


## Custom Fields and Tags

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

  <summary>
    
  </summary>
  <content>
    
    
    
</content>


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


> **Recommended**
> Tags do not need to be namespaced, but for many customers the organization pays off by using namespaced tags when
> it makes sense.


#### Fields
Fields store information about your subscribers, like their language or timezone. Use them to segment subscribers
and personalize your messaging.

Unlike namespaced tags, fields are not limited to a single detail and do not need to be predefined. You can store
strings, numbers, or objects in a field.

#### Best Practices
Use tags for segmentation and fields for more detailed subscriber data. Most setups combine both.


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


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


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

  
    #### NOT Ideal Transactional Email Use Cases
    * CC / BCC recipients
    * Emails that require an attachment (we suggest always using links for emails for best deliverability)
    * Marketing of any kind
    * Promotional content
    * Newsletters
  


#### 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 "~[no-reply@domain.com](mailto:no-reply@domain.com)~" 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.


> 🚨 **Important**
> Transactional emails should **not** be used as substitutes for **marketing** campaigns or **promotional**
>   content.


## 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 recommend these
methods for all subscriber updates, single or bulk.


> These methods cover more than 80% of the API use cases for most customers.


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


  <summary>
    
</summary>
<content>
    
</content>


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

    

    
> ⚠️ **Warning**
> This endpoint is rate-limited and not suitable for loops or bulk creation. Use only for individual subscriber creation.


  
  
**2. Multiple Or Enriched Subscriber Creation**

  
    For creating multiple subscribers or including additional fields:

    

    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:


> Because you can apply as many changes via automations / workflows as you want this is the most flexible method.
> It doesn't require code or deployment changes, and can be completely handled in Bento.


#### Alternative Update Methods

For updates outside of user-triggered actions:

  
**1. Single Attribute Updates**

  
    For quickly updating a specific attribute on a single subscriber:
    
      <summary>
        
      </summary>
      <content>
        
        
      </content>
    

    
> ⚠️ **Warning**
> The Command API is not recommended for multiple updates or bulk operations. Given its heavy rate limit, use the Batch API instead.

  
  
**2. Batch Updates**

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

    

    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:


  <summary>
    
    </summary>
    <content>

    
    
    </content>
  

## Broadcasts

Bento's Broadcasts module allows you to create and manage email broadcast campaigns programmatically. Use it to send
newsletters, announcements, and other one-to-many communications.


  <summary>
    
  </summary>
  <content>
    
    
  </content>


## Sequences and Workflows

Sequences power drip campaigns and time-based email journeys. Workflows are Bento's automation engine
for event-driven campaigns like welcome journeys, abandoned-cart nudges, and re-engagement loops. Both modules support
pagination via an optional `page` parameter.

#### Sequences


  <summary>
    
  </summary>
  <content>
    
  </content>


#### Workflows


> Workflows have a `status` field that indicates whether they are `'live'` or `'draft'`.


## Email Templates

Email templates are used within sequences and workflows. You can retrieve and update templates to manage your email
content programmatically.


  <summary>
    
  </summary>
  <content>
    
  </content>


## Statistics and Reporting

The Stats module gives you access to key metrics for your site, segments, and individual reports. Use these to build
dashboards or monitor campaign performance.


  <summary>
    
  </summary>
  <content>
    
    
  </content>


## Utility Features

These utilities handle common secondary use cases like email validation and blacklist checks.


  <summary>
    
    </summary>
    <content>
      
      
      
      
      
      
    </content>
  


## API Reference


### Core API

- **Analytics** - Main class for initializing the SDK
- `new Analytics(options)` - Create a new instance
- `V1` - Access to the V1 API

### Convenience Methods


| Use Case                                                                                | Convenience Method                                                                                                 |
|-----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
|  Add a new subscriber                          |        |
| Unsubscribe a subscriber                       |  |
| Merge or update 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 Case                                                              | Method                                                                                                                           | API Reference                                                                                                                                         |
|-----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| Import multiple subscribers  |              | [Import Subscribers](/docs/subscribers#import-subscribers) |
| Import multiple events       |                        | [Import Events](/docs/events_api#create-events)            |
| Send multiple emails         |  | [Send Emails](/docs/emails_api#create-emails)              |

#### Commands
| Use Case                                                       | Method                                                                                                   | API Reference                                                                                                                                        |
|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| Add a tag             |            | [Subscriber Upsert](/docs/subscribers#import-subscribers) |
| Remove a tag          |      | [Subscriber Upsert](/docs/subscribers#import-subscribers) |
| Add a field           |        | [Subscriber Upsert](/docs/subscribers#import-subscribers) |
| Remove a field        |  | [Subscriber Upsert](/docs/subscribers#import-subscribers) |
| Subscribe a user      |      | [Subscriber Command](/docs/subscribers#run-command)       |
| Unsubscribe a user    |  | [Subscriber Command](/docs/subscribers#run-command)       |
| Change email address  |  | [Subscriber Command](/docs/subscribers#run-command)       |

#### Experimental
| Use Case                                                              | Method                                                                                                         | API Reference                                                                                                                                   |
|-----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| Validate email address       |    | [Validate Email](/docs/utility#validate-email)       |
| Predict in-domain placement  |        | [Gender Guess](/docs/utility#guess-gender)           |
| Get IP geolocation           |            | [IP Geolocation](/docs/utility#geolocate-ip-address) |
| Check domain/IP blacklist    |  | [Blacklist Check](/docs/utility#search-blacklists)   |
| Check blacklist status (new)  |  | [Blacklist Status](/docs/utility#search-blacklists) |
| Content moderation            |  | --            |
| Geolocate IP (simplified)     |  | [IP Geolocation](/docs/utility#geolocate-ip-address) |

#### Fields
| Use Case                                                 | Method                                                                                                   | API Reference                                                                                                                  |
|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| Get all fields  |                  | [Fields](/docs/fields#get-fields)   |
| Create a field  |  | [Fields](/docs/fields#create-field) |

#### Forms
| Use Case                                                     | Method                                                                                                     | API Reference |
|--------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|---------------|
| Get form responses  |  | --            |

#### Subscribers
| Use Case                                                      | Method                                                                                                             | API Reference                                                                                                                                     |
|---------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| Get subscriber       |      | [Find Subscriber](/docs/subscribers#find-subscriber)   |
| Create a subscriber  |  | [Create Subscriber](/docs/subscribers#find-subscriber) |
| Run command          |              | [Subscriber Commands](/docs/subscribers#run-command)   |

#### Tags
| Use Case                                               | Method                                                                                               | API Reference                                                                                                                      |
|--------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|
| Get all tags  |                  | [List Tags](/docs/tags_api#get-tags)    |
| Create a tag  |  | [Create Tag](/docs/tags_api#create-tag) |

#### Broadcasts
| Use Case                                                                        | Method                                                                                                                           | API Reference                                                                                                                                            |
|---------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Get all broadcasts                     |                                  | [Get Broadcasts](/docs/broadcasts#get-broadcasts)        |
| Create broadcast campaigns             |          | [Create Broadcasts](/docs/broadcasts#create-broadcasts)  |
| Create transactional emails in batch   |                        | [Create Emails](/docs/broadcasts#create-broadcasts)      |

#### Email Templates
| Use Case                                                              | Method                                                                                                                                    | API Reference                                                                                                                                                          |
|-----------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Get email template           |                         | [Get Template](/docs/email_templates_api#get-email-template)            |
| Update email template        |                    | [Update Template](/docs/email_templates_api#update-email-template)      |

#### Sequences
| Use Case                                                               | Method                                                                                                                                                    | API Reference                                                                                                                                                            |
|------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Get all sequences             |                                           | [Get Sequences](/docs/sequences_api#get-sequences)                        |
| Add email to sequence         |            | [Create Sequence Email](/docs/sequences_api#create-sequence-email)        |

#### Stats
| Use Case                                                               | Method                                                                                                                         | API Reference                                                                                                                                          |
|------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| Get site statistics           |                                  | [Site Stats](/docs/stats#get-site-stats)                |
| Get segment statistics        |          | [Segment Stats](/docs/stats#get-segment-stats)          |
| Get report statistics         |              | [Report Stats](/docs/stats#get-report-stats)            |

#### Workflows
| Use Case                                                               | Method                                                                                                                         | API Reference                                                                                                                                            |
|------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Get all workflows             |                | [Get Workflows](/docs/workflows_api#get-workflows)        |


## Troubleshooting


#### Common Errors

|                                                            |                                                                   |
|------------------------------------------------------------|-------------------------------------------------------------------|
| `Not Authorized` | Check your API keys and ensure they have appropriate permissions  |
| `Rate Limited`   | Implement backoff/retry logic for batch operations                |
| `Network Errors` | Check internet connectivity and API endpoint availability         |
| `Exceptions`     | Double 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


**Q: Can I use this SDK in a browser environment?**
A: No, this SDK is designed for server-side Node.js environments as it requires secret API keys.

**Q: How do I handle rate limiting?**
A: Implement exponential backoff when you encounter `RateLimitedError` exceptions.

**Q: What's the maximum batch size for importing subscribers or events?**
A: Up to 1,000 subscribers or events can be imported in a single batch operation.

**Q: How do I track anonymous users?**
A: Currently, the SDK requires an email for all tracking. Anonymous tracking support is planned for future releases.

**Q: Is this SDK compatible with TypeScript?**
A: Yes, the SDK is written in TypeScript and provides full type definitions for improved developer experience.

**Q: How do I configure the request timeout?**
A: Pass `clientOptions: { timeout: 60000 }` when initializing the Analytics client. The default is 30,000ms (30 seconds).

**Q: How can I contribute to the SDK?**
A: Check the GitHub repository at [github.com/bentonow/bento-node-sdk](https://github.com/bentonow/bento-node-sdk) for contribution guidelines, or contact us on Discord.