prontuno/prontuno-laravel
Prontuno for Laravel is a lightweight package that brings Prontuno functionality into your Laravel applications. It offers straightforward Composer installation, simple configuration, and familiar Laravel conventions, making it easy to integrate and use in new or existing projects.
Architecture fit. This is a thin, idiomatic Laravel integration — service provider + facade auto-discovery, a publishable config file, a route middleware alias, and a mail transport registered through Laravel's mail manager. It adds no database tables or migrations, so it is essentially stateless and imposes no schema or persistence decisions on the host application. That is the right shape for a vendor SDK and keeps the blast radius small: you can adopt the mail transport without adopting the API resources, and vice versa.
The strongest architectural signal is that the package sits on top of a framework-agnostic client (prontuno/prontuno-php) and on Laravel's own HTTP client. That means the Laravel layer is a convenience shell rather than a load-bearing abstraction — if the integration lags a Laravel release, a team can drop to the underlying SDK or raw HTTP without re-architecting.
Integration feasibility. High for greenfield or Laravel 12 apps; gated otherwise. Two hard constraints:
Everything else is conventional. Http::fake() working in application tests removes the usual "we need a sandbox tenant before we can write tests" blocker, and env-driven configuration with a publishable config file matches Laravel conventions (php artisan vendor:publish --tag=prontuno-config).
Technical risk. Moderate, concentrated in three places:
MAIL_MAILER touches password resets, receipts, invites, and alerting simultaneously. A transport defect is a user-facing outage, not a degraded feature.Message-ID as the idempotency key, so retries are safe only if the identifier is generated once and preserved across attempt boundaries. If a retry path re-renders the message, dedupe silently fails and you get duplicate email — which is worse than a failure for transactional mail. This needs explicit verification, not inference from release notes.Webhook verification is well-scoped (HMAC over the raw body, 300s default tolerance, typed WebhookEvent, named secrets for multiple endpoints). The residual gap is that a timestamp tolerance bounds replay, it does not prevent it — dedupe on an event identifier is still an application responsibility.
Key questions.
Message-ID generated once per send and preserved across transport retries?Mail::alwaysTo/alwaysFrom, the failover mailer, and MessageSending/MessageSent events?config:cache and env()-at-runtime handled correctly, and is the client safe as a container singleton under Octane and queue workers?Stack fit. Strong for a Laravel 12/13 shop already comfortable with facades, middleware aliases, and Http::fake(). The two-key split (sending vs. management) is good least-privilege design and should be mirrored in how secrets are stored — the management key belongs only in the services that mutate domains, suppressions, webhooks, and API keys, not in the web tier by default. usingApiKey() returning a new client supports multi-tenant use, but it also means per-tenant clients must never be captured into long-lived singletons or Octane-resident state.
Migration path. Do not flip the default mailer first. Sequence it:
composer require. If the app is on Laravel 11 or PHP 8.2, stop — this is an upgrade project, not an integration.Mailable via Mail::mailer('prontuno'), verify headers, attachments, inline images, and that Http::fake() covers the failure paths in tests.failover mailer so a Prontuno outage degrades instead of blocking.Compatibility and sequencing notes. Pin to ~0.1.0 and re-evaluate at each minor. Treat webhook secret rotation and API key rotation as runbook items from day one, not follow-ups. If you maintain multiple Laravel versions across services, expect the package's narrow support matrix to fragment your adoption.
Maintenance. Single-vendor, MIT-licensed, pre-1.0. Expect churn. The mitigations are real but modest: the license permits forking, the API is HTTP/JSON, and the agnostic PHP SDK plus Laravel's HTTP client give you a credible escape hatch. Still, plan for a dependency that needs a human to read changelogs each release rather than one that runs unattended for a year. Assign an owner.
Support. Vendor support terms are undocumented in the release notes — no SLA, no escalation path, no status page reference. For a subsystem that gates password resets, that is a gap. Interim mitigation: wrap sends so a transport exception is captured with the request ID the ApiException exposes (that field is genuinely useful for vendor escalation), and keep a second mailer configured as fallback.
Scaling. Stateless and cheap to scale horizontally; throughput is bounded by queue workers and vendor rate limits, not by the package. Two sizing traps: (a) total send latency is attempts × timeout + backoff, capped by a 60s Retry-After — this must stay comfortably inside your queue retry_after and job timeout, or you get double-sends from the queue re-dispatching a job the transport is still retrying; (b) lazy() iterates every page and belongs in a job or console command, never a request cycle. Inline attachments are held in memory during send — set an explicit ceiling.
Failure modes.
lazy() loops → respect Retry-After, cap concurrency, and cap batch sizes.Ramp-up. Low. A Laravel developer is productive in under a day: facade, middleware alias, config publish, Http::fake() — all familiar idioms, and the README is referenced as covering every feature. The non-obvious parts that need explicit onboarding are the two-key model, the idempotency/Message-ID contract, webhook dedupe discipline, and the retry-budget-vs-queue-timeout math. Documentation beyond the README (upgrade guide, changelog, support matrix) is not evidenced and should be requested from the vendor before you commit critical paths.
How can I help you explore Laravel packages today?