Search by

zerelay / zerelay-php

zerelay

Official PHP SDK for the Zerelay email and SMS API

v0.1.0 2026-11-08 14:12 UTC

This package is not auto-updated.

Last update: 2026-11-08 17:02:35 UTC


README

Official PHP SDK for the Zerelay email and SMS API. PHP 7.4+, with the curl and json extensions.

composer require zerelay/zerelay-php

Send an email

$zerelay = new \Zerelay\Zerelay(getenv('ZERELAY_API_KEY'));

$result = $zerelay->emails->send([
    'to' => 'jane@example.com',
    'subject' => 'Your order has shipped',
    'body' => '<p>It will arrive on Friday.</p>',
]);
echo $result['task_id'];

For cc/bcc, separate text and HTML parts, templates or categories, $zerelay->emails->mailSend([...]) takes the SendGrid v3 /mail/send format.

Send an SMS

$message = $zerelay->sms->send(['to' => '08031234567', 'body' => 'Your code is 4821']);
echo $message['status'], ' ', $message['cost_kobo'];

Test mode

Create a test key (sk_test_...) under API Keys in the dashboard. Test keys check every request exactly like a live key does, but nothing is sent, charged or counted toward your quota. Webhooks still fire, marked "test_mode": true. Send to bounce@simulator.zerelay.com to simulate a bounce.

Verify webhooks

use Zerelay\Webhook;
use Zerelay\WebhookException;

$payload = file_get_contents('php://input');   // the RAW body
try {
    $event = Webhook::verify($payload, getallheaders(), getenv('ZERELAY_WEBHOOK_SECRET'));
} catch (WebhookException $e) {
    http_response_code(400);
    exit($e->getMessage());
}
// $event['event'] is e.g. "delivered", "bounce", "sms.delivered"; de-duplicate on $event['id']
http_response_code(200);

In Laravel, pass $request->getContent() and $request->headers->all().

Errors and retries

Failed requests throw \Zerelay\ZerelayException. Call getStatus() for the HTTP status and getBody() for the response body; getMessage() is the API's explanation. The client retries automatically:

  • Rate limits (429) are always retried, after the Retry-After delay.
  • Network errors and 502/503/504 are retried only when repeating the request is safe. That covers GETs, plus emails->send() and sms->send(), which send an automatic Idempotency-Key.

Change this with new Zerelay($key, ['max_retries' => 0]).

Any other endpoint can be called with $zerelay->request('GET', '/path', ['query' => [...], 'body' => [...]]). The full reference is at https://api.zerelay.com/docs.

License

MIT