zerelay / zerelay-php
Official PHP SDK for the Zerelay email and SMS API
Requires
- php: >=7.4
- ext-curl: *
- ext-json: *
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
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-Afterdelay. - Network errors and 502/503/504 are retried only when repeating the request is safe. That covers GETs, plus
emails->send()andsms->send(), which send an automaticIdempotency-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