Prerequisites
- A Sendbaze API key
- A verified domain. A test key works without one, and so does the shared test address for emails to yourself.
- PHP 8.1 or later with the
curlextension
Guide
1
Set your API key
.env
SENDBAZE_API_KEY=sk_live_xxxxxxxx
2
Send an email
<?php
$payload = [
'from' => 'Yourshop <orders@yourshop.co.za>',
'to' => 'thandi@example.com',
'subject' => 'Your order #1042 has shipped',
'html' => '<p>Tracking: <b>CG123456789ZA</b></p>',
];
$ch = curl_init('https://api.sendbaze.com/v1/emails');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SENDBAZE_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 30,
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException($response['error']['code'] . ': ' . $response['error']['message']);
}
echo $response['id']; // em_01j9...
<?php
use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.sendbaze.key'))
->timeout(30)
->post('https://api.sendbaze.com/v1/emails', [
'from' => 'Yourshop <orders@yourshop.co.za>',
'to' => 'thandi@example.com',
'subject' => 'Your order #1042 has shipped',
'html' => '<p>Tracking: <b>CG123456789ZA</b></p>',
]);
if ($response->failed()) {
report(new RuntimeException($response->json('error.code') . ': ' . $response->json('error.message')));
}
$id = $response->json('id'); // em_01j9...
<?php
use GuzzleHttp\Client;
$client = new Client(['base_uri' => 'https://api.sendbaze.com', 'timeout' => 30]);
$response = $client->post('/v1/emails', [
'headers' => ['Authorization' => 'Bearer ' . getenv('SENDBAZE_API_KEY')],
'json' => [
'from' => 'Yourshop <orders@yourshop.co.za>',
'to' => 'thandi@example.com',
'subject' => 'Your order #1042 has shipped',
'html' => '<p>Tracking: <b>CG123456789ZA</b></p>',
],
]);
$id = json_decode($response->getBody(), true)['id'];
3
Try it
Run the script and open the dashboard Logs.
Examples
Laravel: config and a queued job
config/services.php
'sendbaze' => [
'key' => env('SENDBAZE_API_KEY'),
],
app/Jobs/SendReceipt.php
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Http;
class SendReceipt implements ShouldQueue
{
use Queueable;
public function __construct(public int $orderId, public string $to, public string $name) {}
public function handle(): void
{
Http::withToken(config('services.sendbaze.key'))
->withHeaders(['Idempotency-Key' => "receipt-{$this->orderId}"])
->post('https://api.sendbaze.com/v1/emails', [
'from' => 'orders@yourshop.co.za',
'to' => $this->to,
'templateId' => 'tpl_receipt',
'variables' => ['name' => $this->name, 'order_id' => $this->orderId],
'tags' => ['receipt'],
])
->throw();
}
}
Attach a file
$payload['attachments'] = [[
'filename' => 'invoice-1042.pdf',
'contentType' => 'application/pdf',
'content' => base64_encode(file_get_contents('invoice-1042.pdf')),
]];
Verify a webhook (Laravel)
routes/api.php
Route::post('/webhooks/sendbaze', function (Illuminate\Http\Request $request) {
$raw = $request->getContent();
parse_str(str_replace(',', '&', $request->header('Sendbaze-Signature', '')), $parts);
$expected = hash_hmac('sha256', $parts['t'] . '.' . $raw, config('services.sendbaze.webhook_secret'));
abort_unless(abs(time() - (int) $parts['t']) <= 300 && hash_equals($expected, $parts['v1'] ?? ''), 400);
$event = json_decode($raw, true);
// handle $event['type'] such as "email.bounced"
return response()->json(['received' => true]);
});