Multi-Query Example
This is a short example that showcases a few endpoints most API users will need.
The following guide uses basic Ruby in it's examples. You can use any language of choice in your implementation.
Just make sure that you remember to keep your API keys safe and secure 🙏
To access data in Bento, you'll need three things:
- Your Site Key/UUID.
- Your user's Private API Key.
- Your user's Public API Key.
You can expire your Private and Public Keys but cannot expire your Site Key without a support request. All requests to our API are logged and monitored for anomalies.
All requests to
fetch
have a maximum of 3,600 requests per hour.All requests to
batch
have a maximum of 500 requests per hour.When we chat to developers we typically see a few issues come up when interacting with the API.
The most common issue is incorrect API or Site Keys. If you can't find them, you can raise a support ticket or ask us in Discord and we'll find them for you.
The second most common issue is hitting rate limits (described above). Please make sure you're using the appropriate endpoint for whatever task you are doing in Bento.
To begin, let's start wth using the
fetch/subscribers
endpoint to add a new visitor record into Bento via their email address. In Bento, a subscriber is essentially a visitor with an email added to their profile.
A
GET
request to this endpoint will simply try to find a visitor who has the email you specified to confirm that they have been synced whereas a POST
request will either lookup the visitor or create it by email. For almost all cases, you will want to POST
to the endpoint.create_subscriber.rb
require 'net/http'
require 'uri'
publishable_key = "XXXX-XXXX-XXXX-XXXX"
secret_key = "XXXX-XXXX-XXXX-XXXX"
site_uuid = "XXXX-XXXX-XXXX-XXXX"
uri = URI.parse("https://app.bentonow.com/api/v1/fetch/subscribers")
request = Net::HTTP::Post.new(uri)
request.basic_auth(publishable_key, secret_key)
request.body = JSON.dump({site_uuid: site_uuid, email: "[email protected]"})
request.content_type = "application/json"
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts JSON.parse(response.body)
After running this we will get a response confirming the visitor was added and their details.
{"data"=>{"id"=>"568", "type"=>"visitors", "attributes"=>{"uuid"=>"9b91f034d6692e3ec61830705ceef818", "email"=>"[email protected]", "fields"=>nil, "cached_tag_ids"=>[]}}}
The visitor has now been added to Bento so we're going to want to flesh out their profile with some more detail.
Let's add a
customer
tag to the profile using the fetch/commands
endpoint. We will be using the
add_tag
command instead of the add_tag_via_query
as we do not want to fire any automations.add_tag.rb
uri = URI.parse("https://app.bentonow.com/api/v1/fetch/commands")
request = Net::HTTP::Post.new(uri)
request.basic_auth(publishable_key, secret_key)
request.body = JSON.dump({site_uuid: site_uuid, command: {"command": "add_tag", "email": "[email protected]", "query": "example" }})
request.content_type = "application/json"
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts JSON.parse(response.body)
After running this we'll see that the tag has been added.
{"data"=>{"id"=>"569", "type"=>"visitors", "attributes"=>{"uuid"=>"29114b07bcfedbff608e5223e88fadc0", "email"=>"[email protected]", "fields"=>nil, "cached_tag_ids"=>["233"]}}}
The ID that you see in the
cached_tag_ids
field can be looked up via the fetch/tags
endpoint if you need it. In later API updates we may put the names of the tags in this response but have avoided it for now to optimize the request.
Next, let's add a name to the visitor using the
fetch/commands
endpoint again.add_custom_field.rb
uri = URI.parse("https://app.bentonow.com/api/v1/fetch/commands")
request = Net::HTTP::Post.new(uri)
request.basic_auth(publishable_key, secret_key)
request.body = JSON.dump({site_uuid: site_uuid, email: "[email protected]", command: {"command": "add_field", "email": "[email protected]", "query": {key: "name", value: "Jesse"} }})
request.content_type = "application/json"
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts JSON.parse(response.body)
Great! Looks like the visitor now has a
customer
tag and name added. {"data"=>{"id"=>"569", "type"=>"visitors", "attributes"=>{"uuid"=>"29114b07bcfedbff608e5223e88fadc0", "email"=>"[email protected]", "fields"=>{"name"=>"Jesse"}, "cached_tag_ids"=>["233"]}}}
They're now ready to receive email marketing!
If you visit the dashboard you'll be able to search for this visitor by any of the data you've added. These endpoints are processed and synced to our search engine within 5-15 seconds most of the time.
Now that the above code is sending in user data in real-time it's time to upload all our old subscribers.
For this, we use our
batch/subscribers
endpoint.This takes in an array of subscriber information and queues it up quickly to our importer background jobs. This generally processes over a period of 5 to 50 minutes depending on the queue size, if our importer servers are warm, and how many you're adding.
import_subscribers.rb
import_data = [
{ email: "[email protected]", name: "Jesse", customer_id: "123", favourite_food: "onigiri" },
{ email: "[email protected]", name: "Scott", customer_id: "124" },
]
uri = URI.parse("https://app.bentonow.com/api/v1/batch/subscribers")
request = Net::HTTP::Post.new(uri)
request.basic_auth(publishable_key, secret_key)
request.body = JSON.dump({site_uuid: site_uuid, subscribers: import_data })
request.content_type = "application/json"
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts JSON.parse(response.body)
Once this runs the data will be added to a queue and you will see a count as the response. No further action is required and you can just wait for the import to finish running in your account.
publishable_key = "XXXX-XXXX-XXXX-XXXX"
secret_key = "XXXX-XXXX-XXXX-XXXX"
site_uuid = "XXXX-XXXX-XXXX-XXXX"
import_data = [
{ email: "[email protected]", type: "$custom_event", fields: {"first_name": "Jesse"}, details: {"custom_stat": 1000}},
{ email: "[email protected]", type: "$custom_event_with_no_details", fields: {"first_name": "Jesse", "last_name": "Hanley"}},
{ email: "[email protected]", type: "$custom_event_with_workflow_bypass", details: {"bypass_workflows": 'true'}},
{ email: "[email protected]", type: "$custom_event_with_nothing_else"},
{ email: "[email protected]", type: "$purchase", fields: {"first_name": "Jesse"}, details: {"unique": {"key": "test123" }, "value": {"currency": "USD", "amount": 8000}}},
{ email: "[email protected]", type: "$purchase", fields: {"first_name": "Jesse"}, details: {"unique": {"key": "test123" }, "value": {"currency": "USD", "amount": 8000}, 'cart' => { 'items' => [{'product_sku': 'SKU123', 'product_name': 'Test', 'quantity': 100 }], 'abandoned_checkout_url': "https://test.com" }}},
{ email: "[email protected]", type: "$backdated_event", date: 3.years.ago }
]
uri = URI.parse("https://app.bentonow.com/api/v1/batch/events")
request = Net::HTTP::Post.new(uri)
request.basic_auth(publishable_key, secret_key)
request.body = JSON.dump({site_uuid: site_uuid, events: import_data })
request.content_type = "application/json"
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts JSON.parse(response.body)
In the above script, we're including new events, old events, and events that bypass automations. Without the bypass key we'd expect them to trigger every Workflow that's turned on.
Last modified 11mo ago