ravisystems / ravimail-php
Official PHP SDK for the RaviMail REST API v1 (api.ravimail.com.br).
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10.0
This package is not auto-updated.
Last update: 2026-05-21 01:35:25 UTC
README
Official PHP client for the RaviMail REST API v1.
Zero framework dependencies — only ext-curl + ext-json.
Why this exists. RaviMail is a Brazilian email infrastructure platform with 155 documented REST endpoints. This SDK gives you typed access to all of them, with idiomatic PHP 8.1+ ergonomics and clear exception hierarchy.
Installation
composer require ravisystems/ravimail-php
Requirements: PHP 8.1+, ext-curl, ext-json.
Quickstart — Hello World
use Ravimail\Client; $rm = new Client('rvm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); // Send a transactional email $resp = $rm->transactional->send([ 'to' => 'recipient@example.com', 'from' => 'you@yourdomain.com', 'subject' => 'Welcome to the show', 'html' => '<h1>Glad you’re here</h1>', ]); echo $resp['data']['message_id']; // msg_xxxxxxxxxxxx
That's it. The SDK takes care of auth, JSON encoding, error parsing, and timeouts.
Test mode (no billing, no real send)
Any token prefixed with rvm_test_* enables sandbox mode automatically. You can
develop end-to-end without spending credits.
$test = new Client('rvm_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); $test->transactional->send([/* ... */]); // returns msg_sandbox_xxx, doesn't bill
Send to the Mailbox Simulator for
deterministic scenarios: bounce@simulator.ravimail.com.br, complaint@...,
opened@..., etc.
Available resources
All 23 resources mirror the REST API exactly. Most are CRUD; a few have helpers.
| Resource | What it covers |
|---|---|
$rm->me |
Token info + quotas |
$rm->transactional |
send, batch, list, get |
$rm->contacts |
CRUD + tags + suppress + bulk import |
$rm->lists |
CRUD |
$rm->templates |
CRUD + render + versioning |
$rm->campaigns |
CRUD + start/pause/resume/cancel/duplicate |
$rm->domains |
Add, verify, upgrade-to-panel |
$rm->files |
Upload (attachments) |
$rm->webhooks |
Endpoints + deliveries + rotateSecret + signature verifier |
$rm->suppression |
Suppress / unsuppress |
$rm->analytics |
Summary / timeseries / by domain, IP, node, ISP, device, country / heatmap |
$rm->events |
List + SSE stream URL |
$rm->verification |
Email + batch (DNS + MX + disposable + role detection) |
$rm->segments |
Dynamic segments + compute |
$rm->exports |
Async CSV jobs |
$rm->inboundRoutes |
Inbound parsing → forward webhook |
$rm->drips |
Drip campaigns + steps + subscribe |
$rm->subaccounts |
Multi-tenant (agency mode) |
$rm->reputation |
Score per domain / IP / node + summary |
$rm->customFields |
Custom field schema CRUD |
$rm->reports |
Scheduled reports |
$rm->account |
Billing + balance |
$rm->smtpRelay |
SMTP credentials lifecycle |
See examples/ for runnable snippets covering the most common flows.
Idempotency keys
For any write operation you want to retry safely, pass an Idempotency-Key:
$rm->transactional->send($payload, idempotencyKey: 'order-1024-confirmation');
The API guarantees that the second call with the same key returns the original response, byte for byte, even days later.
Webhook signature verification (server-side)
Webhooks are HMAC-signed with the per-endpoint signing_secret returned at
creation time.
use Ravimail\Resources\Webhooks; $ok = Webhooks::verifySignature( $_SERVER['HTTP_X_RAVIMAIL_SIGNATURE'], file_get_contents('php://input'), 'whsec_your_endpoint_secret' ); if (!$ok) { http_response_code(401); exit; }
Constant-time comparison via hash_equals internally — no timing leak.
Error handling
All non-2xx responses throw. Catch the most specific exception first.
use Ravimail\Exception\{ ApiException, AuthenticationException, ValidationException, RateLimitException }; try { $rm->transactional->send([/* ... */]); } catch (ValidationException $e) { // 422 — bad payload; $e->getMessage() has the field-level detail } catch (RateLimitException $e) { // 429 — back off and retry } catch (AuthenticationException $e) { // 401 — token invalid, revoked, or wrong environment } catch (ApiException $e) { // any other 4xx/5xx }
The base ApiException exposes ->getCode() (HTTP status) and ->getMessage()
(server's title — detail if present).
Configuration
$rm = new Client( token: 'rvm_live_...', baseUrl: 'https://api.ravimail.com.br', // override for staging if you have one timeout: 30, // seconds );
Links
- 📚 Full docs — concept guides, cookbooks, troubleshooting
- 🔌 API reference — 155 endpoints, all groups
- 📝 Changelog — releases history
- 💡 Conceitos — warmup, bounces, DKIM/SPF/DMARC explained
- 🐛 Issues — bug reports & feature requests
- 🤝 Contributing
License
MIT © Ravi Systems LTDA