- PHP 5.5 or higher
- Guzzle HTTP client 6.5+ or 7.0+
- Composer
This library is fully compatible with PHP 8.2 and later versions. The library supports both Guzzle 6.5+ and Guzzle 7.x to ensure compatibility across different PHP versions:
- PHP 7.x: Compatible with Guzzle 6.5+ and Guzzle 7.x
- PHP 8.0+: Recommended to use Guzzle 7.x for best performance and to avoid deprecation warnings
- PHP 8.2+: Requires Guzzle 7.x to avoid deprecation warnings
When installing on PHP 8.2+, Composer will automatically install Guzzle 7.x.
The client library includes comprehensive model support with all fields returned by the Sendbee API. Recent enhancements include:
Contact Model:
modified_at- Timestamp when contact was last modifiedhas_messaging_consent- Boolean indicating if contact has given messaging consent
ContactTag Model:
editable- Boolean indicating if tag can be editeddisable_contact- Boolean indicating if tag disables contacticons- Array of icon data
ContactNote Model:
id- UUID identifier for the note
Message Model:
id- UUID identifier for the messagefail_reason- Reason for message failure (when applicable)action- Action associated with the messagemeta_data- Additional metadata as an arrayfrom_user_id- UUID of sender userto_user_id- UUID of recipient user
MessageTemplate Model:
rejected_reason- Reason for template rejection (when applicable)name- Template namecategory- Template categorybutton_tags- Collection of tags for buttons
MessageTemplateButton Model:
icon- Icon data as an array/objectaction- Button action typeflow_action- Flow action identifiernavigate_screen- Screen navigation targetflow_id- Associated flow identifierurl_type- Type of URL for the button
All models are automatically populated from API responses, ensuring type safety and easy access to all available data.
The recommended way to install Sendbee API is with Composer.
curl -sS https://getcomposer.org/installer | phpYou can add Sendbee API as a dependency using the composer.phar CLI:
php composer.phar require sendbee/apiIf Composer is available globally on your system, you can run the following from your project root.
composer require sendbee/apiIf you have an existing project that uses Composer and has composer.json file,
you can specify sendbee/api as a dependency.
{
"require": {
"sendbee/api": "~1.0"
}
}After adding a dependency you should tell composer to update dependencies
composer updateAfter installing, you need to require Composer's autoloader:
require 'vendor/autoload.php';You can find out more on how to install Composer, configure autoloading, and other best-practices for defining dependencies at Composer.
To initialize the API client, you'll need a public key and secret. That data is available in your Sendbee dashboard.
$sendbeeApi = new \Sendbee\Api\Client($public_key, $secret);// optional parameters
$params = [
'tags' => '', // Filter contacts by tag
'status' => '', // Filter contacts by status
'search_query' => '', // Filter contacts by query string
'page' => 1 // Page number for pagination
];
try {
$response = $sendbeeApi->getContacts($params);
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $contact) {
/**
* @var $contact \Sendbee\Api\Models\Contact
*/
echo "\n ID: ", $contact->id;
echo "\n name: ", $contact->name;
echo "\n phone: ", $contact->phone;
echo "\n created_at: ", $contact->created_at;
echo "\n status: ", $contact->status;
echo "\n folder: ", $contact->folder;
foreach ($contact->tags as $tag) {
/**
* @var $tag \Sendbee\Api\Models\ContactTag
*/
echo "\n tag -> id: ", $tag->id;
echo "\n tag -> name: ", $tag->name;
}
foreach ($contact->notes as $note) {
/**
* @var $note \Sendbee\Api\Models\ContactNote
*/
echo "\n note -> value: ", $note->value;
}
foreach ($contact->contact_fields as $contactField) {
/**
* @var $contactField \Sendbee\Api\Models\ContactContactField
*/
echo "\n contact_field -> key: ", $contactField->key;
echo "\n contact_field -> value: ", $contactField->value;
}
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$contactData = [
// contact phone number, MANDATORY
'phone' => '+...',
// feel free to specify other optional contact data here
// tag new contact
// if tag doesn't exist, it will be created
'tags' => ['...',],
// contact name
'name' => '...',
// contact fields
// contact fields must be pre-created in Sendbee Dashboard
// any non-existent field will be ignored
'contact_fields' => ['key' => 'value'],
// your notes about subscriber
'notes' => ['...'],
// prevent sending browser push notification and email
// notification to agents, when new contact subscribes
// (default is True)
'block_notifications' => true,
// prevent sending automated template messages to newly
// subscribed contact (if any is set in Sendbee Dashboard)
// (default is True)
'block_automation' => true
];
try {
$response = $sendbeeApi->subscribeContact($contactData);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Could not subscribe a contact. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $contact \Sendbee\Api\Models\Contact
*/
$contact = $response->getData();
// contact is now subscribed (created)
// $contact contains the newly created contact data
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$contactData = [
// contact id, MANDATORY
'id' => '...',
// feel free to specify other optional contact data here
// tag new contact
// if tag doesn't exist, it will be created
'tags' => ['...',],
// contact name
'name' => '...',
// contact fields
// contact fields must be pre-created in Sendbee Dashboard
// any non-existent field will be ignored
'contact_fields' => ['...' => '...'],
// your notes about subscriber
// TAKE CARE, notes are not replaced but are instead appended to existing notes
'notes' => ['...'],
// prevent sending browser push notification and email
// notification to agents, when new contact subscribes
// (default is True)
'block_notifications' => true,
// prevent sending automated template messages to newly
// subscribed contact (if any is set in Sendbee Dashboard)
// (default is True)
'block_automation' => true
];
try {
$response = $sendbeeApi->updateContact($contactData);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Could not update a contact. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $contact \Sendbee\Api\Models\Contact
*/
$contact = $response->getData();
// contact is now updated
// $contact contains the updated contact data
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}// optional parameters
$params = [
'name' => '', // Name of the tag
'page' => 1 // Page number for pagination
];
try {
$response = $sendbeeApi->getTags($params);
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $tag) {
/**
* @var $tag \Sendbee\Api\Models\ContactTag
*/
echo "\n ID: ", $tag->id;
echo "\n name: ", $tag->name;
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// tag name, MANDATORY
'name' => '...'
];
try {
$response = $sendbeeApi->createTag($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $tag \Sendbee\Api\Models\ContactTag
*/
$tag = $response->getData();
print_r($tag);
// tag is now created
// $tag contains the newly created tag data
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// tag id, MANDATORY
'id' => '...',
// tag name, MANDATORY
'name' => '...'
];
try {
$response = $sendbeeApi->updateTag($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $tag \Sendbee\Api\Models\ContactTag
*/
$tag = $response->getData();
// tag is now updated
// $tag contains the updated tag data
print_r($tag);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// tag id, MANDATORY
'id' => '...',
];
try {
$response = $sendbeeApi->deleteTag($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $message \Sendbee\Api\Models\ServerMessage
*/
$message = $response->getData();
// record is now deleted
// $message contains server info message
print_r($message);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$params = [
'search_query' => '', // Filter by query string
'page' => 1 // Page number for pagination
];
try {
$response = $sendbeeApi->getContactFields($params);
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $field) {
/**
* @var $tag \Sendbee\Api\Models\ContactField
*/
echo "\n ID: ", $field->id;
echo "\n type: ", $field->type;
echo "\n name: ", $field->name;
foreach ($field->options as $option) {
/**
* @var $option string
*/
echo "\n field -> option: ", $option;
}
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// name, MANDATORY
'name' => 'field name',
// type, one of ['text', 'number', 'list', 'date', 'boolean'], MANDATORY
'type' => 'text',
// List of options. Send it only if the field type is a list.
// values are strings
'options' => []
];
try {
$response = $sendbeeApi->createContactField($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $contactField \Sendbee\Api\Models\ContactField
*/
$contactField = $response->getData();
// contact field is now created
// $contactField contains the newly created contact field data
print_r($contactField);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// id, MANDATORY
'id' => '...',
// name, MANDATORY
'name' => 'field name update',
// type, one of ['text', 'number', 'list', 'date', 'boolean'], MANDATORY
'type' => 'text',
// List of options. Send it only if the field type is a list.
// values are strings
'options' => []
];
try {
$response = $sendbeeApi->updateContactField($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $contactField \Sendbee\Api\Models\ContactField
*/
$contactField = $response->getData();
// contact field is now updated
// $contactField contains the updated contact field data
print_r($contactField);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// id, MANDATORY
'id' => '...',
];
try {
$response = $sendbeeApi->deleteContactField($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $message \Sendbee\Api\Models\ServerMessage
*/
$message = $response->getData();
// record is now deleted
// $message contains server info message
print_r($message);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}// optional parameters
$params = [
// Filter conversations by folder. Specify open, done, spam or notified
'folder' => '',
// Any kind of string that will be used to perform filtering
'search_query' => '',
// Page number for pagination
'page' => 1
];
try {
$response = $sendbeeApi->getConversations($params);
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $conversation) {
/**
* @var $conversation \Sendbee\Api\Models\Conversation
*/
echo "\n ID: ", $conversation->id;
echo "\n folder: ", $conversation->folder;
echo "\n chatbot_active: ", $conversation->chatbot_active;
echo "\n platform: ", $conversation->platform;
echo "\n created_at: ", $conversation->created_at;
echo "\n contact -> id: ", $conversation->contact->id;
echo "\n contact -> name: ", $conversation->contact->name;
echo "\n contact -> phone: ", $conversation->contact->phone;
echo "\n last_message -> direction: ", $conversation->last_message->direction;
echo "\n last_message -> status: ", $conversation->last_message->status;
echo "\n last_message -> inbound_sent_at: ", $conversation->last_message->inbound_sent_at;
echo "\n last_message -> outbound_sent_at: ", $conversation->last_message->outbound_sent_at;
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}// parameters
$params = [
// Conversation UUID, MANDATORY
'conversation_id' => '...'
];
try {
$response = $sendbeeApi->getConversation($params);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
/**
* @var $conversation \Sendbee\Api\Models\Conversation
*/
$conversation = $response->getData();
echo "\n ID: ", $conversation->id;
echo "\n folder: ", $conversation->folder;
echo "\n chatbot_active: ", $conversation->chatbot_active;
echo "\n platform: ", $conversation->platform;
echo "\n created_at: ", $conversation->created_at;
echo "\n contact -> id: ", $conversation->contact->id;
echo "\n contact -> name: ", $conversation->contact->name;
echo "\n contact -> phone: ", $conversation->contact->phone;
echo "\n last_message -> direction: ", $conversation->last_message->direction;
echo "\n last_message -> status: ", $conversation->last_message->status;
echo "\n last_message -> inbound_sent_at: ", $conversation->last_message->inbound_sent_at;
echo "\n last_message -> outbound_sent_at: ", $conversation->last_message->outbound_sent_at;
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}#update-single-conversation
// parameters
$params = [
// Conversation UUID, MANDATORY
'conversation_id' => '...',
// Assigned "folder" - 'open' or 'done'
'folder' => 'open|done'
];
try {
$response = $sendbeeApi->updateConversation($params);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $message) {
/**
* @var $message \Sendbee\Api\Models\Message
*/
echo "\n body: ", $message->body;
echo "\n media_type: ", $message->media_type;
echo "\n media_url: ", $message->media_url;
echo "\n status: ", $message->status;
echo "\n direction: ", $message->direction;
echo "\n sent_at: ", $message->sent_at;
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}// parameters
$params = [
// Conversation UUID, MANDATORY
'conversation_id' => '...',
// Page number for pagination
'page' => 1
];
try {
$response = $sendbeeApi->getMessages($params);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $message) {
/**
* @var $message \Sendbee\Api\Models\Message
*/
echo "\n body: ", $message->body;
echo "\n media_type: ", $message->media_type;
echo "\n media_url: ", $message->media_url;
echo "\n status: ", $message->status;
echo "\n direction: ", $message->direction;
echo "\n sent_at: ", $message->sent_at;
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}// optional parameters
$params = [
'status' => 'pending|approved|rejected', // Fetch approved or unapproved templates
'search_query' => '', // Filter by query string
'page' => 1 // Page number for pagination
];
try {
$response = $sendbeeApi->getMessageTemplates($params);
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $messageTemplate) {
/**
* @var $messageTemplate \Sendbee\Api\Models\MessageTemplate
*/
echo "\n ID: ", $messageTemplate->id;
echo "\n status: ", $messageTemplate->status;
echo "\n attachment: ", $messageTemplate->attachment;
echo "\n keyword: ", $messageTemplate->keyword;
echo "\n text: ", $messageTemplate->text;
echo "\n language: ", $messageTemplate->language;
echo "\n rejected_reason: ", $messageTemplate->rejected_reason;
foreach ($messageTemplate->tags as $tag) {
/**
* @var $tag \Sendbee\Api\Models\MessageTemplateTag
*/
echo "\n tag -> name: ", $tag->name;
}
foreach ($messageTemplate->buttons as $button) {
/**
* @var $tag \Sendbee\Api\Models\MessageTemplateButton
*/
echo "\n button -> index: ", $tag->index;
echo "\n button -> type: ", $tag->type;
echo "\n button -> title: ", $tag->title;
echo "\n button -> value: ", $tag->value;
}
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$data = [
// phone number to send the message to, MANDATORY
'phone' => '+...',
// keyword of an existing template message you are using, MANDATORY
'template_keyword' => '...',
// language code of an existing template message you are using, MANDATORY
'language' => 'en',
// tags, key-value pairs of data that is injected in placeholders, MANDATORY
// example:
// template message is 'Your order {{order}} has been dispatched. Please expect delivery by {{date}}'
// tags are ['order' => 55, 'date' => '2020-12-12']
// final message will be 'Your order 55 has been dispatched. Please expect delivery by 2020-12-12'
'tags' => [],
// Set to true to disable turning-off chatbot
'prevent_bot_off' => true,
// send attachment url for media template mesages
'attachment' => 'http...'
];
try {
$response = $sendbeeApi->sendMessageTemplate($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $messageInfo \Sendbee\Api\Models\SentMessage
*/
$messageInfo = $response->getData();
// $messageInfo contains message information
print_r($messageInfo);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}You can send either text message or media message.
For media message, following formats are supported:
Audio: AAC, M4A, AMR, MP3, OGG OPUS
video: MP4, 3GPP
Image: JPG/JPEG, PNG
Documents: PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX
$data = [
// phone number to send the message to, MANDATORY
'phone' => '+...',
// message text, MANDATORY
'text' => '...',
// Media URL for media message
'media_url' => '',
// Set to true to disable turning-off chatbot
'prevent_bot_off' => true,
];
try {
$response = $sendbeeApi->sendMessage($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $messageInfo \Sendbee\Api\Models\SentMessage
*/
$messageInfo = $response->getData();
// $messageInfo contains message information
print_r($messageInfo);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$params = [
// Filter teams by member UUID - optional
'member_id' => '...',
// Page number for pagination
'page' => 1
];
try {
$response = $sendbeeApi->getTeams($params);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $team) {
/**
* @var $team \Sendbee\Api\Models\Team
*/
echo "\n id: ", $team->id;
echo "\n name: ", $team->name;
foreach ($team->members as $member) {
/**
* @var $member \Sendbee\Api\Models\TeamMember
*/
echo "\n member -> id: ", $member->id;
echo "\n member -> name: ", $member->name;
echo "\n member -> role: ", $member->role;
echo "\n member -> online: ", $member->online;
echo "\n member -> available: ", $member->available;
}
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}$params = [
// Filter members by team UUID - optional
'team_id' => '...',
// Page number for pagination
'page' => 1
];
try {
$response = $sendbeeApi->getMembers($params);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
// everything is OK
$data = $response->getData();
foreach ($data as $member) {
/**
* @var $member \Sendbee\Api\Models\Member
*/
echo "\n id: ", $member->id;
echo "\n name: ", $member->name;
echo "\n role: ", $member->role;
echo "\n online: ", $member->online;
echo "\n available: ", $member->available;
foreach ($member->teams as $team) {
/**
* @var $team \Sendbee\Api\Models\MemberTeam
*/
echo "\n member -> id: ", $team->id;
echo "\n member -> name: ", $team->name;
}
}
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}Every contact is linked with conversation with an agent.
Conversation could be handled by an agent or a bot (automation).
Every time a message has been sent to a contact by an agent or using the API,
the bot is automatically turned off for that conversation - except when you set
'prevent_bot_off' to true via API call (see Send message).
Use the example below to change the chatbot status based on your use case.
$data = [
// conversation_id, MANDATORY
'conversation_id' => '...',
// boolean value, true to enable chatbot, false to disable, MANDATORY
'active' => true | false
];
try {
$response = $sendbeeApi->chatbotActivity($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $tag \Sendbee\Api\Models\ServerMessage
*/
$message = $response->getData();
// chatbot activity is now set
// $message contains server info message
print_r($message);
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}You can also check if chatbot is turned on or off for a conversation.
$data = [
// conversation_id, MANDATORY
'conversation_id' => '...'
];
try {
$response = $sendbeeApi->getChatbotActivity($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}
if ($response->isSuccess()) {
/**
* @var $status \Sendbee\Api\Models\ChatbotStatus
*/
$status = $response->getData();
echo "\n conversation_id: ", $status->text;
echo "\n chatbot_active: ", $status->chatbot_active ? 'ON' : 'OFF';
} else {
/**
* @var $error \Sendbee\Api\Transport\ResponseError
*/
$error = $response->getError();
if ($error) {
// handle error
echo "\n error type: ", $error->type;
echo "\n error details: ", $error->detail;
}
}All API methods return a Sendbee\Api\Transport\Response object.
Only exception is when some required parameter is missing or there are network issues - in that case an exception is thrown.
The response object wraps the raw server response into corresponding objects and exposes methods to inspect received data.
/**
* @var $response \Sendbee\Api\Transport\Response
*/
$response = $sendbeeApi->getContacts();
// check if request was successful
$success = $response->isSuccess();
// get HTTP status code the server returned
$statusCode = $response->getHttpStatus();
// get data wrapped into appropriate object(s)
$data = $response->getData();
// get pagination data (when available)
$pagination = $response->getMeta();
// get error if API call failed
$error = $response->getError();
// get a warning message sent by API (when available)
$warning = $response->getWarning();
// get response headers
$headers = $response->getHeaders();
// get rate limit information from response headers
$rateLimit = $response->getRateLimitLimit(); // requests per minute (60)
$rateLimitRemaining = $response->getRateLimitRemaining(); // remaining requests
$rateLimitReset = $response->getRateLimitReset(); // timestamp when limit resets
// if you prefer to deal with the raw server response, that is available as well
$rawResponseString = $response->getRawBody();The Sendbee API enforces a rate limit of 60 requests per minute. When this limit is exceeded, the API returns a 429 Too Many Requests status code along with a Retry-After header indicating how many seconds to wait before retrying.
The PHP client library automatically handles rate limiting for you:
- When a 429 response is received, the client automatically retries the request up to 3 times
- The client reads the
Retry-Afterheader and waits the specified duration before retrying (defaults to 30 seconds if header is missing) - Retry attempts are logged to help with debugging
- This behavior is transparent and requires no additional code from you
// No special handling needed - rate limiting is automatic
$response = $sendbeeApi->getContacts();
// Even when paginating through many pages, the client handles rate limits automatically
for ($page = 1; $page <= 126; $page++) {
$response = $sendbeeApi->getContacts(['page' => $page]);
// Process results...
}You can monitor your rate limit usage by inspecting response headers:
$response = $sendbeeApi->getContacts();
// Get rate limit information
$limit = $response->getRateLimitLimit(); // 60 (requests per minute)
$remaining = $response->getRateLimitRemaining(); // How many requests left
$reset = $response->getRateLimitReset(); // Unix timestamp when limit resets
echo "Rate limit: $remaining/$limit requests remaining";
echo "Resets at: " . date('Y-m-d H:i:s', $reset);The client is configured with the following timeouts:
- Request timeout: 30 seconds (maximum time for the entire request to complete)
- Connection timeout: 10 seconds (maximum time to establish a connection)
These timeouts are designed to work well with the API's rate limiting and ensure reliable operation even during high-volume operations.
Pagination is available on all client methods that accept a page parameter. Those methods are:
- getContacts()
- getTags()
- getContactFields()
- getConversations()
- getMessages()
- getMessageTemplates()
To get the first page of results you can omit the page parameter or set it to 1
$sendbeeApi->getContacts(['page' => 1]);
$sendbeeApi->getTags(['page' => 1]);
$sendbeeApi->getContactFields(['page' => 1]);
$sendbeeApi->getConversations(['page' => 1]);
$sendbeeApi->getMessages(['page' => 1, 'conversation_id' => '...']);
$sendbeeApi->getMessageTemplates(['page' => 1]);Calling API methods that get a list of resources will return a Sendbee\Api\Transport\Response object containing pagination.
Calling getMeta() on it will return pagination information.
/**
* @var $response \Sendbee\Api\Transport\Response
*/
$response = $sendbeeApi->getContacts();
$pagination = $response->getMeta();
echo "\n Total records: ", $pagination->total;
echo "\n Current records from: ", $pagination->from;
echo "\n Current records to: ", $pagination->to;
echo "\n Current page: ", $pagination->current_page;
echo "\n Last page: ", $pagination->last_page;
echo "\n How many records per page: ", $pagination->per_page;Sendbee API client for PHP will throw an Exception is some required data is missing or it is unable to connect to Sendbee. You should wrap API calls in a try-catch block and handle thrown exceptions.
You should only encounter 2 types of exceptions:
-
\Sendbee\Api\Support\DataException- Thrown when required data is missing. Message contains more information. -
\GuzzleHttp\Exception\GuzzleException- Thrown by underlying GuzzleHttp library. Indicates Sendbee backend is unavailable/unreachable
// example of exception checking when calling some API method
// in this example, we are trying to create a new tag
$data = [];
try {
$response = $sendbeeApi->createTag($data);
} catch (\Sendbee\Api\Support\DataException $ex) {
// handle missing data
// this happens when required data was not provided
echo "Missing required data. ", $ex->getMessage();
} catch (\Exception $ex) {
// handle exception thrown by GuzzleHttp
// this is most likely due to a network issue
echo "Could not contact backend endpoint. ", $ex->getMessage();
}After activating your webhook URL in Sendbee Dashboard, we will start sending requests on that URL depending on which webhook type is linked with that webhook URL.
Every request that we make will have authorization token in header, like this:
{
...
'X-Authorization': '__auth_token_here__',
...
}
To authenticate requests that we make to your webhook URL, take this token from request header and check it using Sendbee API Client:
$requestIsValid = \Sendbee\Api\Client::verifyToken($secret, $token);