Installation
composer require sendpulse/rest-api
Configure API Credentials
Fetch API_USER_ID and API_SECRET from SendPulse API Settings.
Store them securely (e.g., Laravel .env):
SENDPULSE_API_USER_ID=your_user_id
SENDPULSE_API_SECRET=your_secret_key
Initialize Client
use Sendpulse\RestApi\ApiClient;
use Sendpulse\RestApi\Storage\FileStorage;
$apiClient = new ApiClient(
env('SENDPULSE_API_USER_ID'),
env('SENDPULSE_API_SECRET'),
new FileStorage() // For file uploads (optional)
);
First Use Case: Fetch Mailing Lists
$mailingLists = $apiClient->get('addressbooks', [
'limit' => 100,
'offset' => 0
]);
CRUD Operations
Use get(), post(), put(), delete() methods for standard API calls:
// Create a mailing list
$newList = $apiClient->post('addressbooks', [
'name' => 'New Subscribers',
'description' => 'List for marketing emails'
]);
// Update a mailing list
$apiClient->put("addressbooks/{$listId}", [
'name' => 'Updated List'
]);
File Uploads (e.g., for Email Templates)
$apiClient->post('messages', [
'file' => new \CURLFile(PATH_TO_ATTACH_FILE, 'application/pdf', 'template.pdf')
]);
Pagination Handling Loop through paginated results:
$offset = 0;
while (true) {
$subscribers = $apiClient->get('addressbooks/{$listId}/subscribers', [
'limit' => 100,
'offset' => $offset
]);
if (empty($subscribers['items'])) break;
$offset += 100;
}
Webhook Integration
Use webhooks endpoint to subscribe to events:
$webhook = $apiClient->post('webhooks', [
'url' => 'https://your-app.com/sendpulse-webhook',
'events' => ['campaign.sent', 'subscriber.unsubscribed']
]);
Service Provider Binding
Bind the client in AppServiceProvider for dependency injection:
public function register()
{
$this->app->singleton(ApiClient::class, function ($app) {
return new ApiClient(
env('SENDPULSE_API_USER_ID'),
env('SENDPULSE_API_SECRET'),
new FileStorage(storage_path('app/sendpulse'))
);
});
}
Facade for Convenience Create a facade to simplify usage:
// app/Facades/SendPulse.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class SendPulse extends Facade {
protected static function getFacadeAccessor() { return 'sendpulse'; }
}
Register in config/app.php:
'sendpulse' => \Sendpulse\RestApi\ApiClient::class,
Jobs for Async Operations Offload long-running tasks (e.g., bulk subscriber imports) to queues:
// app/Jobs/SendEmailCampaign.php
use Sendpulse\RestApi\ApiClient;
class SendEmailCampaign implements ShouldQueue {
protected $apiClient;
public function __construct(ApiClient $apiClient) { $this->apiClient = $apiClient; }
public function handle() {
$this->apiClient->post('messages/send', [
'addressbook_id' => $this->addressbookId,
'message_id' => $this->messageId
]);
}
}
Event Listeners Trigger actions on SendPulse webhook events:
// app/Listeners/HandleSendPulseWebhook.php
public function handle($event) {
$data = json_decode($event->getContent(), true);
if ($data['event'] === 'campaign.sent') {
// Update DB or notify users
}
}
Authentication Errors
401 Unauthorized due to incorrect credentials or expired tokens.API_USER_ID/API_SECRET and ensure they’re not hardcoded. Use Laravel’s .env and env() helper.$apiClient = new ApiClient(..., null, null, [
'debug' => true,
'log_file' => storage_path('logs/sendpulse.log')
]);
Rate Limiting
429 Too Many Requests if exceeding SendPulse’s rate limits.if ($e->getCode() === 429) {
sleep(2 ** $retryCount); // Exponential backoff
$retryCount++;
}
File Uploads
FileStorage with a dedicated directory and set curl options:
$apiClient = new ApiClient(..., new FileStorage(storage_path('app/sendpulse')));
$apiClient->setCurlOption(CURLOPT_TIMEOUT, 300); // 5-minute timeout
Webhook Verification
X-Signature header doesn’t match.public function handle($request, Closure $next) {
$expectedSignature = hash_hmac('sha256', $request->getContent(), env('SENDPULSE_API_SECRET'));
if ($request->header('X-Signature') !== $expectedSignature) {
abort(403);
}
return $next($request);
}
Enable Debug Mode
Pass a debug array to the ApiClient constructor:
$apiClient = new ApiClient(..., null, null, [
'debug' => true,
'log_file' => storage_path('logs/sendpulse.log')
]);
Inspect Raw Responses
Catch ApiClientException to debug:
try {
$response = $apiClient->get('addressbooks');
} catch (ApiClientException $e) {
var_dump([
'error' => $e->getMessage(),
'http_code' => $e->getCode(),
'raw_response' => $e->getResponse(),
'request_data' => $e->getRequestData()
]);
}
Test with Sandbox Use SendPulse’s sandbox environment for testing:
$apiClient = new ApiClient('sandbox_user_id', 'sandbox_secret');
Custom Storage for Files
Extend FileStorage to integrate with S3 or other storage:
use Sendpulse\RestApi\Storage\StorageInterface;
class S3Storage implements StorageInterface {
public function saveFile($filePath, $fileName) { /* ... */ }
public function deleteFile($filePath) { /* ... */ }
}
Middleware for Requests Add request/response middleware:
$apiClient = new ApiClient(..., null, null, [
'middleware' => [
function ($request) {
$request['custom_field'] = 'value';
},
function ($response) {
if ($response->getStatusCode() === 200) {
$response->setData(['processed' => true]);
}
}
]
]);
Mocking for Tests
Use PHP’s Mockery to mock ApiClient in unit tests:
$mockClient = Mockery::mock(ApiClient::class);
$mockClient->shouldReceive('get')
->with('addressbooks')
->andReturn(['items' => []]);
Batch Processing For bulk operations (e.g., subscriber imports),
How can I help you explore Laravel packages today?