Download the PHP package samuelterra22/volpa-mail-laravel without Composer
On this page you can find all versions of the php package samuelterra22/volpa-mail-laravel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download samuelterra22/volpa-mail-laravel
More information about samuelterra22/volpa-mail-laravel
Files in samuelterra22/volpa-mail-laravel
Package volpa-mail-laravel
Short Description SDK e Mail Transport do Volpa Mail para Laravel — envie e-mails transacionais via API do Volpa Mail.
License MIT
Homepage https://github.com/samuelterra22/volpa-mail-laravel
Informations about the package volpa-mail-laravel
Volpa Mail for Laravel
Official Volpa Mail SDK and Mail Transport for Laravel. Send transactional
emails through the Volpa Mail API using Laravel's native
Mail facade or the SDK directly — with typed DTOs, retries, and rich error
handling.
What this package is: the client SDK that your Laravel apps install to send mail through Volpa Mail. It does not contain the Volpa Mail backend (the multi-tenant sending platform).
Table of contents
- Requirements
- Feature scope
- Installation
- Configuration
- Quick start
- Using as a Laravel Mailer
- Using as a direct SDK
- Idempotency-Key on send
- Suppressions
- Contacts & contact lists
- Broadcasts
- Webhook verification
- Email payload reference
- Attachments
- Checking delivery status
- Error handling
- Troubleshooting
- Testing & quality
- Contributing — Conventional Commits & releases
- License
Requirements
| Requirement | Version |
|---|---|
| PHP | ^8.3 |
Laravel (illuminate/*) |
^11.0 or ^12.0 |
symfony/mailer |
^7.0 |
| A Volpa Mail account | API key generated in the panel (Settings → API Keys) |
Feature scope
| Capability | Status |
|---|---|
Send transactional email (POST /emails) |
✅ |
Get email status (GET /emails/{id}) |
✅ |
Laravel Mail::mailer('volpa-mail') transport |
✅ |
Typed DTOs (SendEmailData, Address, Attachment, SentEmail) |
✅ |
| Automatic retries + typed exceptions | ✅ |
Idempotency-Key header on send |
✅ |
429 / Retry-After handling |
✅ |
| Suppressions | ✅ |
| Contacts / Contact lists | ✅ |
| Broadcasts / Campaigns | ✅ |
| Webhook signature verification (custom HMAC-SHA256) | ✅ |
Batch send (POST /emails/batch) |
🔜 roadmap |
| Domain API | — not implemented (no backend endpoint) |
Installation
The service provider and the VolpaMail facade are auto-discovered — no manual
registration needed.
Publish the config (optional, only if you want to tweak defaults):
This creates config/volpa-mail.php.
Configuration
Add your credentials to .env:
All available environment variables:
| Env variable | Config key | Default | Description |
|---|---|---|---|
VOLPA_MAIL_API_KEY |
api_key |
(none — required) | Tenant API key. Sent in the X-API-Key header on every request. Generated in the Volpa Mail panel under Settings → API Keys. |
VOLPA_MAIL_BASE_URL |
base_url |
https://mail.volpa.com.br/v1 |
Base endpoint of the REST API. Includes the /v1 version prefix, no trailing slash. |
VOLPA_MAIL_TIMEOUT |
timeout |
10 |
Per-request timeout, in seconds. |
VOLPA_MAIL_RETRY_TIMES |
retry.times |
2 |
Retry attempts on network failure or 5xx. |
VOLPA_MAIL_RETRY_SLEEP |
retry.sleep |
200 |
Wait between retries, in milliseconds. |
The API key is mandatory. If it is missing, the SDK throws
VolpaMailException::missingApiKey()on the first call — fail fast instead of silently dropping mail.
Quick start
Using as a Laravel Mailer
Register the mailer in config/mail.php:
Make it the default mailer:
…or use it on demand for a single message:
All standard Mailable features work as usual — Markdown mailables,
attachments, cc/bcc, replyTo, custom headers. The transport converts the
Symfony message into a Volpa Mail API call and records the returned email ID as
the message ID (setMessageId($sent->id)) so you can correlate it with webhook
events on the backend.
Using as a direct SDK
For fine-grained control, templates, and variables, call the SDK directly.
With a friendly array
With a typed DTO
Idempotency-Key on send
Pass a unique key as the second argument to send() to enable idempotent
delivery. The backend replays the same response for a repeated key (24-hour
TTL) instead of sending a duplicate email. On a body mismatch for the same key,
the API returns 409 Conflict.
The recommended key format is UUID v7 (time-ordered):
Store the key with the job so retries reuse it safely.
Suppressions
Manage the suppression list (hard bounces, complaints, unsubscribes, etc.):
SuppressionReason cases: HardBounce, SoftBounceRepeated, Complaint,
Unsubscribe, Manual, InvalidAddress.
Contacts & contact lists
ContactStatus cases: Active, Unsubscribed, Bounced, Complained.
Broadcasts
BroadcastStatus cases: Draft, Scheduled, Sending, Sent, Canceled,
Failed. Use $status->isFinal() to check if the broadcast has reached a
terminal state.
Webhook verification
The Volpa Mail backend sends events to your endpoint (e.g. delivered,
bounced) signed with a custom HMAC-SHA256 scheme.
Signature format — the delivery header is X-VolpaMail-Signature:
The signed string is <unix_timestamp>.<raw_json_body>. The tolerance window
defaults to 300 seconds.
Verifying in a controller
Or verify raw payload + header string manually:
The event type is also available in the
X-VolpaMail-Eventheader if you need it before parsing the body.
Email payload reference
Fields accepted by send() (array keys / DTO constructor args). Empty optional
fields are omitted from the request body.
| Field (array) | DTO arg | Type | Required | Notes |
|---|---|---|---|---|
from |
from |
array{email,name?} / Address |
✅ | Sender. |
to |
to |
list of {email,name?} / Address[] |
✅ | At least one recipient. |
cc |
cc |
list / Address[] |
— | Carbon copy. |
bcc |
bcc |
list / Address[] |
— | Blind carbon copy. |
reply_to |
replyTo |
list / Address[] |
— | Reply-To addresses. |
subject |
subject |
string |
⚠️ | Required unless a template_id supplies it. |
html |
html |
string |
— | HTML body. |
text |
text |
string |
— | Plain-text body. |
template_id |
templateId |
string |
— | Template slug or ID on the backend. |
variables |
variables |
array<string,mixed> |
— | Template variables. |
tags |
tags |
string[] |
— | Tags for filtering/analytics. |
headers |
headers |
array<string,string> |
— | Custom X-* headers. |
attachments |
attachments |
Attachment[] |
— | See Attachments. |
Attachments
Build an attachment from a file on disk (it is read and base64-encoded for you):
Or construct it explicitly with already-encoded content:
Checking delivery status
EmailStatus cases:
| Case | Value | Terminal? |
|---|---|---|
Pending |
pending |
— |
Queued |
queued |
— |
Scheduled |
scheduled |
— |
Processing |
processing |
— |
Sent |
sent |
— |
Delivered |
delivered |
✅ |
Opened |
opened |
— |
Clicked |
clicked |
— |
Deferred |
deferred |
— |
Bounced |
bounced |
✅ |
SoftBounced |
soft_bounced |
— |
Complained |
complained |
✅ |
Rejected |
rejected |
✅ |
Failed |
failed |
✅ |
Canceled |
canceled |
✅ |
Error handling
Any non-2xx response (or a missing API key) raises a
SamuelTerra\VolpaMail\Exceptions\VolpaMailException:
The exception parses both error envelopes returned by the backend:
{"error":{"code","message"}} and {"message","errors"}. On HTTP 429, check
$e->retryAfter before scheduling a retry.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
VolpaMailException: Missing Volpa Mail API key |
VOLPA_MAIL_API_KEY not set (or config cached). |
Set the env var, then php artisan config:clear. |
401 Unauthorized |
Invalid/revoked API key, or key from the wrong tenant. | Re-issue the key in the panel and update .env. |
403 Forbidden |
IP allowlist on the key, or sender not verified. | Allow your server IP / verify the sender domain in the panel. |
422 Unprocessable Entity |
Validation failed (e.g. missing subject and template_id). |
Inspect $e->errors for the offending fields. |
Mail silently not sent via Mail:: |
volpa-mail mailer not registered in config/mail.php. |
Add the mailer block shown above. |
| Connection timeouts | Network/firewall or low VOLPA_MAIL_TIMEOUT. |
Raise the timeout / check egress to mail.volpa.com.br. |
Testing & quality
The test suite uses Pest and
Orchestra Testbench with
Http::fake() — no real network calls are made.
Run all three before pushing:
Contributing — Conventional Commits & releases
This package is versioned automatically. When you push to main, the CI
workflow runs the tests; if they pass, the Release workflow reads the commit
messages, computes the next version (SemVer), and publishes the tag + GitHub
Release — which syncs Packagist. You never create a tag by hand.
For this to work, commits must follow the Conventional Commits standard:
Types and version impact
| Commit type | Example | Version effect |
|---|---|---|
feat: |
feat: add ContactResource |
minor (1.2.0 → 1.3.0) |
fix: |
fix: fix retry on 429 |
patch (1.2.0 → 1.2.1) |
perf: |
perf: reduce allocation in toArray |
patch |
BREAKING CHANGE |
see below | major (1.2.0 → 2.0.0) |
chore: docs: test: ci: style: refactor: build: |
— | none (no release) |
Since the workflow uses
default_bump: false, a push that contains only no-effect commits (e.g. justdocs:) does not generate a release — correct SemVer behavior.
Breaking change (major)
Use ! after the type or a BREAKING CHANGE: footer:
Examples
Before pushing, make sure the gate is green locally:
License
MIT. See LICENSE.md.
All versions of volpa-mail-laravel with dependencies
illuminate/contracts Version ^11.0 || ^12.0
illuminate/mail Version ^11.0 || ^12.0
illuminate/support Version ^11.0 || ^12.0
symfony/mailer Version ^7.0