mailkube/mailkube-php
A PHP client for the Mailkube API that makes it easy to integrate Mailkube email and messaging features into your applications, with simple request handling, configurable authentication, and predictable responses.
v1.3.0 is a minor release with no breaking changes — upgrading from 1.2.x is a safe composer update mailkube/mailkube-php. Two things changed: the docs/support links in the package now point at hosts that actually resolve, and the client gained $client->credential->info().
Minimum steps to get productive:
$client->credential->info(). This is the fastest smoke test in the package: it proves the key is right, the network path works, and tells you which key you're actually using.The first use case to wire up is almost always a queued transactional send (password reset, receipt, invite) rather than a marketing blast — it forces you to solve config, error handling, and retries on a small, observable surface.
Singleton client in the container. Resolve once per request/worker, not per call:
$this->app->singleton(MailkubeClient::class, fn () => new MailkubeClient(
apiKey: config('services.mailkube.key'),
));
In Laravel, prefer a thin Mailkube wrapper class over injecting the vendor client into every controller — it gives you a seam for fakes and keeps SDK types out of your domain code.
Per-tenant / multi-key clients. If you send on behalf of multiple accounts, don't mutate a shared client's key. Use a small factory that builds a client from a tenant's stored key, memoized per tenant ID. credential->info() becomes genuinely valuable here: log it once when a tenant's key is saved, so you can confirm the tenant pasted a key for the right account and environment before their mail silently misbehaves.
Startup / health check. Call credential->info() in a deploy verification step or a scheduled health check and log the key identifier and environment. It answers "did the prod deploy pick up the sandbox key again?" without sending a test email. Cache the result (config or short-lived cache entry) — see gotchas.
Queued sends with explicit failure semantics. Wrap sends in a job with $tries and $backoff, and distinguish retryable failures (timeouts, 5xx, rate limits) from permanent ones (invalid recipient, unverified domain, auth failure) so you don't burn retries on a 422. Log the provider message/request ID on every send — it's the only handle support will ask for.
Testing. Fake at the HTTP layer (Http::fake() / Guzzle mock handler) rather than mocking the SDK's own classes, so you're asserting the actual payload shape. Keep one non-faked integration test behind an env guard that sends credential->info() only.
Notifications. If you already use Laravel's mail notifications, the cheapest integration is a custom mail transport or notification channel that delegates to the client — you keep the Notification API and gain Mailkube's delivery metadata.
credential->info() is a live API call. Don't put it in a middleware, a Blade view, or a per-request boot path. Cache it for minutes-to-hours; treat it like any other read endpoint.credential->info() returns metadata about the key — log the ID/label/environment, redact anything secret-shaped, and be careful with Log::info($response) on raw responses.php artisan config:cache after changing MAILKUBE_* env vars, or you'll debug a phantom "wrong key" for an hour. Same trap if you build the client in a service provider closure that captured config before the cache existed.mailkube/mailkube-php exactly, bump to ^1.3 to get the credential endpoint — otherwise the smoke test above will fatal on an undefined property.How can I help you explore Laravel packages today?