Subscribers

On this page, we’ll dive into managing your subscribers. When you are a new customer with an existing list you might use the import subscribers endpoint.

Manage your subscribers. When you are a new customer with an existing list you might use the import subscribers endpoint. Find and search subscribers with convenient lookup methods.

Method Endpoint Description
POST /v1/batch/subscribers Import Subscribers
GET /v1/fetch/search Search Subscribers
GET /v1/fetch/subscribers Find Subscriber
POST /v1/fetch/subscribers Create Subscriber
POST /v1/fetch/commands Run Command

The subscriber model

The Subscriber model captures primary identity details and any custom key/value data you want to store alongside a person.

email · string

Email address for the subscriber.

first_name · string

Optional first name value.

last_name · string

Optional last name value.

tags · string

Comma-separated list of tags to apply. Missing tags are created automatically.

remove_tags · string

Comma-separated list of tags to remove when importing.

fields · object

Additional key/value fields stored on the subscriber (e.g., `{ "role": "customer" }`).

POST /v1/batch/subscribers

Import Subscribers

Queue up to 1,000 subscribers per call. Bento mirrors the same background jobs used by manual imports, making this the safest path for large list migrations.

Required attributes

email · string
Email address for each subscriber in the payload.

Optional attributes

first_name · string
Subscriber first name.
last_name · string
Subscriber last name.
tags · string
Comma-separated tags to add.
remove_tags · string
Comma-separated tags to remove.
fields · object
Custom key/value pairs to persist on the subscriber.

cURL

bash
curl -u publishableKey:secretKey \
  -X POST "https://app.bentonow.com/api/v1/batch/subscribers?site_uuid=ExampleID1234" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "subscribers": [
      {
        "email": "test@test.com",
        "first_name": "John",
        "last_name": "Doe",
        "tags": "lead,mql",
        "remove_tags": "customers",
        "some_other_field": "some value"
      }
    ]
  }'

JavaScript

javascript
const axios = require('axios');

let data = {
  subscribers: [
    {
      email: 'test@test.com',
      first_name: 'John',
      last_name: 'Doe',
      tags: 'lead,mql',
      remove_tags: 'customers',
      some_other_field: 'some value'
    }
  ]
};

let config = {
  method: 'post',
  url: 'https://app.bentonow.com/api/v1/batch/subscribers',
  params: { site_uuid: 'ExampleID1234' },
  auth: {
    username: 'publishableKey',
    password: 'secretKey'
  },
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  data: JSON.stringify(data)
};

axios(config)
  .then((response) => {
    console.log(JSON.stringify(response.data, null, 2));
  })
  .catch((error) => {
    console.error('Error:', error.response ? error.response.data : error.message);
  });

Node SDK

javascript
bento.V1.Batch.importSubscribers({
  subscribers: [
    {
      email: 'test@bentonow.com',
      age: 21,
    },
    {
      email: 'test2@bentonow.com',
      some_custom_variable: 'tester-123',
      primary_user: true,
    }
  ],
})
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

Laravel SDK

php
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();

Python

python
from bento_api import BentoAPI
import os

api = BentoAPI(
  site_uuid=os.getenv('BENTO_SITE_UUID'),
  username=os.getenv('BENTO_PUBLISHABLE_KEY'),
  password=os.getenv('BENTO_SECRET_KEY')
)
subscribers = [
  {"email": "user1@example.com", "first_name": "User", "last_name": "One"},
  {"email": "user2@example.com", "first_name": "User", "last_name": "Two"}
]
result = api.batch_create_subscribers(subscribers)

C#

csharp
public class SubscriberExample
{
  private readonly IBentoSubscriberService _subscriberService;

  public SubscriberExample(IBentoSubscriberService subscriberService)
  {
    _subscriberService = subscriberService;
  }

  public async Task SubscriberExamples()
  {
    var subscribers = new List<SubscriberRequest>
    {
      new(
        Email: "user1@example.com",
        FirstName: "User",
        LastName: "One",
        Tags: new[] { "imported", "test" }
      )
    };
    var importResponse = await _subscriberService.ImportSubscribersAsync<dynamic>(subscribers);
  }
}

Go

go
subscribers := []*bento.SubscriberInput{
  {
    Email:     "user1@example.com",
    FirstName: "John",
    LastName:  "Doe",
    Tags:      []string{"imported", "customer"},
  },
}

if err := client.ImportSubscribers(ctx, subscribers); err != nil {
  log.Fatal(err)
}

Response

Returns the number of subscribers that were accepted into the import queue.

Response body

json
{
  "result": 1
}
GET /v1/fetch/search

Search Subscribers

Returns the 100 most recent subscribers who match your query so you can audit engagement across time.

Required attributes

page · integer
Result page to fetch.

Optional attributes

created_at · object
Object with `gt` and `lt` ISO date filters.
updated_at · object
Object with `gt` and `lt` ISO date filters.
last_event_at · object
Object with `gt` and `lt` ISO date filters.
unsubscribed_at · object
Object with `gt` and `lt` ISO date filters.

cURL

bash
curl -L -u publishableKey:secretKey \
  -X GET "https://app.bentonow.com/api/v1/fetch/search?site_uuid=ExampleID1234" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-raw '{
    "page": 1,
    "created_at": { "gt": "string", "lt": "string" },
    "updated_at": { "gt": "string", "lt": "string" },
    "last_event_at": { "gt": "string", "lt": "string" },
    "unsubscribed_at": { "gt": "string", "lt": "string" }
  }'

JavaScript

javascript
const axios = require('axios');

let data = {
  page: 1,
  created_at: { gt: 'string', lt: 'string' },
  updated_at: { gt: 'string', lt: 'string' },
  last_event_at: { gt: 'string', lt: 'string' },
  unsubscribed_at: { gt: 'string', lt: 'string' }
};

let config = {
  method: 'get',
  url: 'https://app.bentonow.com/api/v1/fetch/search',
  params: { site_uuid: 'ExampleID1234' },
  auth: {
    username: 'publishableKey',
    password: 'secretKey'
  },
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  data: JSON.stringify(data)
};

axios(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

Ruby

ruby
require "uri"
require "json"
require "net/http"

url = URI("https://app.bentonow.com/api/v1/fetch/search?site_uuid=ExampleID1234")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Content-Type"] = "application/json"
request["Accept"] = "application/json"
request["Authorization"] = "Basic BASE64ENCODE(USERNAME+PASSWORD)"
request.body = JSON.dump({
  page: 1,
  created_at: { gt: "string", lt: "string" },
  updated_at: { gt: "string", lt: "string" },
  last_event_at: { gt: "string", lt: "string" },
  unsubscribed_at: { gt: "string", lt: "string" }
})

response = https.request(request)
puts response.read_body

Response

Returns subscriber entries plus pagination metadata for the query.

Response body

json
{
  "data": [
    {
      "id": "string",
      "type": "string",
      "attributes": {
        "uuid": "string",
        "email": "string",
        "fields": {},
        "cached_tag_ids": ["string"],
        "unsubscribed_at": "string",
        "navigation_url": "string"
      }
    }
  ],
  "meta": {
    "page": 0,
    "query": {
      "email": {
        "not": "string"
      }
    }
  }
}
GET /v1/fetch/subscribers

Find Subscriber

Retrieve a single subscriber by email or UUID to inspect their profile.

Required attributes

email · string
Email address to look up.

Optional attributes

uuid · string
Subscriber UUID when you prefer an immutable lookup.

cURL

bash
curl -L -u publishableKey:secretKey \
  -X GET "https://app.bentonow.com/api/v1/fetch/subscribers?site_uuid=ExampleID1234&email=test@example.com" \
  -H "Accept: application/json"

JavaScript

javascript
const axios = require('axios');

let config = {
  method: 'get',
  url: 'https://app.bentonow.com/api/v1/fetch/subscribers',
  params: {
    site_uuid: 'ExampleID1234',
    email: 'test@example.com'
  },
  auth: {
    username: 'publishableKey',
    password: 'secretKey'
  },
  headers: {
    'Accept': 'application/json'
  }
};

axios(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

Node SDK

javascript
bento.V1.Subscribers.getSubscribers({ email: 'test@bentonow.com' })
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

Laravel SDK

php
use Bentonow\BentoLaravel\Facades\Bento;

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

Ruby

ruby
subscriber = Bento::Subscribers.find_by(email: 'test@bentonow.com')
subscriber&.email

Python

python
from bento_api import BentoAPI
import os

api = BentoAPI(
  site_uuid=os.getenv('BENTO_SITE_UUID'),
  username=os.getenv('BENTO_PUBLISHABLE_KEY'),
  password=os.getenv('BENTO_SECRET_KEY')
)
subscriber = api.get_subscriber(email="example@example.com")

Swift

swift
let bentoAPI = BentoAPI(siteUUID: "BENTO_SITE_UUID", username: "BENTO_PUBLISHABLE_KEY", password: "BENTO_SECRET_KEY")

do {
    let response = try await bentoAPI.fetchSubscriber(email: "user@example.com")
    print("Subscriber UUID: \(response.data.attributes.uuid)")
} catch {
    print("Error fetching subscriber: \(error)")
}

C#

csharp
public class SubscriberExample
{
  private readonly IBentoSubscriberService _subscriberService;

  public SubscriberExample(IBentoSubscriberService subscriberService)
  {
    _subscriberService = subscriberService;
  }

  public async Task SubscriberExamples()
  {
    var findResponse = await _subscriberService.FindSubscriberAsync<dynamic>("test@example.com");
  }
}

Go

go
subscriber, err := client.FindSubscriber(ctx, "test@example.com")
if err != nil {
  log.Fatal(err)
}
fmt.Printf("Subscriber details: %+v\n", subscriber)

Response

Returns the subscriber resource if a match is found.

Response body

json
{
  "data": {
    "id": "string",
    "type": "string",
    "attributes": {
      "uuid": "string",
      "email": "string",
      "fields": {},
      "cached_tag_ids": ["string"]
    }
  }
}
POST /v1/fetch/subscribers

Create Subscriber

Create a subscriber inline and queue them for indexing so downstream tooling stays in sync.

Required attributes

subscriber.email · string
Email address for the new subscriber.

Optional attributes

subscriber.first_name · string
Optional first name.
subscriber.last_name · string
Optional last name.
subscriber.tags · string
Optional comma-separated tag list.
subscriber.fields · object
Optional key/value fields to persist.

cURL

bash
curl -L -u publishableKey:secretKey \
  -X POST "https://app.bentonow.com/api/v1/fetch/subscribers?site_uuid=ExampleID1234" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-raw '{
    "subscriber": {
      "email": "example@example.com"
    }
  }'

JavaScript

javascript
const axios = require('axios');

let data = {
  subscriber: {
    email: 'example@example.com'
  }
};

let config = {
  method: 'post',
  url: 'https://app.bentonow.com/api/v1/fetch/subscribers',
  params: { site_uuid: 'ExampleID1234' },
  auth: {
    username: 'publishableKey',
    password: 'secretKey'
  },
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  data: JSON.stringify(data)
};

axios(config)
  .then((response) => {
    console.log(JSON.stringify(response.data, null, 2));
  })
  .catch((error) => {
    console.error('Error:', error.response ? error.response.data : error.message);
  });

Node SDK

javascript
bento.V1.Subscribers.createSubscriber({ email: 'test@bentonow.com' })
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

Laravel SDK

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

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

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

Python

python
from bento_api import BentoAPI
import os

api = BentoAPI(
  site_uuid=os.getenv('BENTO_SITE_UUID'),
  username=os.getenv('BENTO_PUBLISHABLE_KEY'),
  password=os.getenv('BENTO_SECRET_KEY')
)
new_subscriber = api.create_subscriber(email="newuser@example.com")

C#

csharp
public class SubscriberExample
{
  private readonly IBentoSubscriberService _subscriberService;

  public SubscriberExample(IBentoSubscriberService subscriberService)
  {
    _subscriberService = subscriberService;
  }

  public async Task SubscriberExamples()
  {
    var subscriberRequest = new SubscriberRequest(
      Email: "test@example.com",
      FirstName: "John",
      LastName: "Doe",
      Tags: new[] { "lead", "mql" }
    );

    var createResponse = await _subscriberService.CreateSubscriberAsync<dynamic>(subscriberRequest);
  }
}

Go

go
input := &bento.SubscriberInput{
  Email:     "test@example.com",
  FirstName: "John",
  LastName:  "Doe",
  Tags:      []string{"new-user"},
}

newSubscriber, err := client.CreateSubscriber(ctx, input)
if err != nil {
  log.Fatal(err)
}
fmt.Printf("Created subscriber: %+v\n", newSubscriber)

Response

Returns the newly created subscriber payload.

Response body

json
{
  "data": {
    "id": "12345",
    "type": "visitors",
    "attributes": {
      "uuid": "123-123-123-123-123",
      "email": "test@example.com",
      "fields": {},
      "cached_tag_ids": ["123"]
    }
  }
}
POST /v1/fetch/commands

Run Command

Execute subscriber commands (add/remove tags, update fields, subscribe/unsubscribe, change email) when batch endpoints do not fit.

Required attributes

command · array
Array of command objects with `command`, `email`, and optional `query` payloads.

cURL

bash
curl -L -u publishableKey:secretKey \
  -X POST "https://app.bentonow.com/api/v1/fetch/commands?site_uuid=ExampleID1234" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data-raw '{
    "command": [
      {
        "command": "add_tag",
        "email": "test@test.com",
        "query": "test"
      },
      {
        "command": "change_email",
        "email": "test@test.com",
        "query": "new@test.com"
      }
    ]
  }'

JavaScript

javascript
const axios = require('axios');

let data = {
  command: [
    { command: 'add_tag', email: 'test@test.com', query: 'test' },
    { command: 'add_tag_via_event', email: 'test@test.com', query: 'test' }
  ]
};

let config = {
  method: 'post',
  url: 'https://app.bentonow.com/api/v1/fetch/commands',
  params: { site_uuid: 'ExampleID1234' },
  auth: {
    username: 'publishableKey',
    password: 'secretKey'
  },
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  data: JSON.stringify(data)
};

axios(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

Node SDK

javascript
bento.V1.Commands.addTag({ email: 'test@bentonow.com', tagName: 'Test Tag' })
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

Laravel SDK

php
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();

Python

python
from bento_api import BentoAPI
import os

api = BentoAPI(
  site_uuid=os.getenv('BENTO_SITE_UUID'),
  username=os.getenv('BENTO_PUBLISHABLE_KEY'),
  password=os.getenv('BENTO_SECRET_KEY')
)
commands = [
  {"command": "add_tag", "email": "user@example.com", "query": "new_tag"},
  {"command": "remove_tag", "email": "user@example.com", "query": "old_tag"}
]
result = api.execute_commands(commands)

Swift

swift
let bentoAPI = BentoAPI(siteUUID: "BENTO_SITE_UUID", username: "BENTO_PUBLISHABLE_KEY", password: "BENTO_SECRET_KEY")

let command = SubscriberCommand.addTag(email: "user@example.com", tag: "VIP")
do {
    let response = try await bentoAPI.executeCommand(command)
    print("Tag added successfully")
} catch {
    print("Error adding tag: \(error)")
}

C#

csharp
public class CommandExample
{
  private readonly IBentoCommandService _commandService;

  public CommandExample(IBentoCommandService commandService)
  {
    _commandService = commandService;
  }

  public async Task CommandExamples()
  {
    var commandRequest = new CommandRequest(
      Command: "add_tag",
      Email: "user@example.com",
      Query: "new_tag"
    );

    var response = await _commandService.ExecuteCommandAsync<dynamic>(commandRequest);
  }
}

Go

go
commands := []bento.CommandData{
  {
    Command: bento.CommandAddTag,
    Email:   "user@example.com",
    Query:   "new-tag",
  },
  {
    Command: bento.CommandRemoveTag,
    Email:   "user@example.com",
    Query:   "old-tag",
  },
}

if err := client.SubscriberCommand(ctx, commands); err != nil {
  log.Fatal(err)
}

Response

Returns the subscriber object after the command(s) complete.

Response body

json
{
  "data": {
    "id": "12345",
    "type": "visitors",
    "attributes": {
      "uuid": "123-123-123-123-123",
      "email": "test@example.com",
      "fields": {},
      "cached_tag_ids": ["123"]
    }
  }
}

Need the original Markdown? Open raw file