Download the PHP package mosaiqo/mailer-php without Composer

On this page you can find all versions of the php package mosaiqo/mailer-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package mailer-php

Mailer PHP SDK

Official PHP SDK for the Mailer REST API v1. It wraps the transactional send, contacts, lists, tags, templates, messages and campaigns endpoints behind typed resources and readonly DTOs, with first-class error handling and idempotency support — plus an optional, batteries-included Laravel integration.

⚠️ Read-only mirror. This repo is an automated split of the SDK from a private monorepo. Do not open pull requests here — they can't be merged (the mirror is force-pushed) and will be auto-closed. Found a bug or have a request? Open an issue (see CONTRIBUTING).

🤖 Integrating with an AI agent? Start with AGENTS.md — a terse, imperative integration playbook with the human-gate steps called out. This README is the full human reference.

Features

Requirements

Installation

The package is published on Packagist — require it directly with Composer, no repository entry or Git/SSH access needed:

Path repository (monorepo development)

When developing inside the Mailer monorepo, point Composer at the package directory with a path repository:

Quick start: integrate into a Laravel app

The full, copy-pasteable recipe to route a real Laravel app's email through a mailer-app instance. (Detailed behavior and options are documented further down.)

1. Require the package (published on Packagist):

2. Set the environment variables.

Where to get the API key. In mailer-app, open Settings → API keys for the project you want to send from and create a key (it is shown once — copy it straight into MAILER_API_TOKEN). Keys are per project, so the key also selects which project's sender, templates and contacts the sends use.

3. Add the mailer mailer to config/mail.php.

4. Send. Nothing else in your mailing code changes:

Or call the API client directly — e.g. to render a stored template by slug with per-recipient variables:

That is the whole integration. The rest of this document covers the SDK's full surface and the transport's detailed behavior.

Plain PHP usage

Batch sends

No attachments in batches. /send/batch rejects messages.*.attachments with a 422 — attachments are single-send only. Call send()->email() per recipient instead (the Laravel mail transport does this fan-out for you).

Notifications (in-app & push)

Send a notification to a contact over one or more channels. Without a channels key the SDK sends in_app; pass channels to fan out (e.g. in-app and push):

Per-channel failures are data, not exceptions. Each requested channel comes back as a NotificationChannelResult, so one channel failing never aborts the others — and when no channel can be queued (the API replies 422 with the same envelope) you still get a NotificationResult (anyQueued() is false) rather than a thrown exception. A real validation error (missing title, etc.) still throws ValidationException.

status errorCode Meaning
queued Accepted for delivery on that channel.
failed_precondition push_provider_not_configured Push not set up for the project.
blocked recipient_blocked Recipient is suppressed/blocked.
blocked quota_exceeded Monthly email/notification quota is out.
blocked sandbox_cap_exceeded Sandbox project send cap reached.

Push prerequisites: the project must have a push provider configured and the contact must have at least one registered device token (see below).

Push device tokens

Register and remove the device tokens push notifications are delivered to. The contact is upserted with transactional semantics (no double opt-in):

The platform is the native device platform: ios or android. This endpoint registers native FCM device tokens only — web push uses a separate VAPID subscription flow, so web is not accepted here (passing it yields a 422).

Registering a token already owned by another contact in the project moves it to this contact; a contact is capped at 20 devices (the oldest is evicted past the cap). Removing a token from an unknown contact raises a NotFoundException (contact_not_found).

Idempotency

email() and batch() accept a named idempotencyKey argument, sent as the Idempotency-Key header. Re-sending with the same key returns the original result instead of creating a duplicate. While the first request is still in flight a concurrent retry with the same key gets a 409 — surfaced as a base MailerException with code idempotency_conflict; an empty or over-long key is rejected with a 422 ValidationException (code invalid_idempotency_key).

Other resources

The campaigns resource is intentionally read-only: it never sends or schedules a campaign. Trigger mass sends from the dashboard, not the SDK.

Paginated endpoints return a Paginated DTO exposing ->data (mapped DTOs), ->meta and ->links. The tags endpoint returns a flat Tag[] array.

Automatic pagination

Paginated resources also expose a cursor() generator that lazily walks every page for you, fetching one page at a time and yielding each mapped DTO. You never track page numbers — just iterate:

A cursor() returns a plain \Generator (the core SDK never depends on Illuminate). In a Laravel app you can wrap it in a LazyCollection to use the collection pipeline:

Resilience (automatic retries)

When you let the SDK build its own HTTP client (the default — you do not inject a Guzzle client), it installs an automatic retry middleware with exponential backoff.

Tune it through the optional options argument (4th constructor parameter):

When you inject your own Guzzle client it is used as-is — add the retry middleware yourself via Mailer\Sdk\Http\RetryMiddleware::make() if you want it.

Error handling

Every non-2xx response is mapped to a typed exception. All exceptions extend Mailer\Sdk\Exception\MailerException and expose:

Exception HTTP status Notes
AuthenticationException 401 Missing/invalid/expired token.
NotFoundException 404 e.g. contact_not_found, template_not_found, message_not_found; a sandbox simulate() from a production token gets a bare 404 (no code).
ValidationException 422 Validation failures and domain rejections (recipient_suppressed, quota_exceeded, template_not_found, invalid_status_transition, sandbox invalid_event_for_channel / link_index_out_of_range, ...). Adds errors(): array (field => messages).
RateLimitException 429 Adds retryAfter(): ?int parsed from the Retry-After header.
MailerConfigurationException — (local) Missing/empty/placeholder base URL or empty token; thrown at client construction before any request.
UnsupportedFeatureException — (local) The send relies on something the /send API has no field for, or that the SDK config disables (e.g. attachments with mailer-sdk.mail.attachments = 'fail').
AttachmentsTooLargeException — (local) The decoded attachments of one send exceed the 10 MB total limit; thrown before any upload. getErrorCode() is attachments_too_large, the same code the server returns for the 422.
MailerException any other Base class; also the catch-all for unexpected non-2xx statuses.

Testing with the sandbox

A sandbox project lets your CI exercise the real send pipeline without touching production data or real inboxes. The API token is the routing: a sandbox token quietly captures everything it sends and unlocks the event simulator; a production token can't even see the simulator (it gets a bare 404). So the same code under test only needs a different MAILER_API_TOKEN.

The recipe is: send → read it back from messages() (the sandbox inbox) → simulate an event → assert.

Notes and safety properties:

Laravel integration

The package is auto-discovered (no manual provider/alias registration). It registers a container-bound MailerClient singleton, a Mailer facade, a mailer mail transport and a mailer notification channel — all driven by the same mailer-sdk config.

Configuration

Publish the config file:

Then set the env vars (every key below maps to config/mailer-sdk.php):

Resolve the client from the container:

The resilience knobs (MAILER_TIMEOUT, MAILER_RETRIES, MAILER_RETRY_BASE_DELAY, MAILER_RETRY_MAX_DELAY) are wired into the container-bound client automatically.

Connection config. MAILER_API_TOKEN is required — an empty token throws a Mailer\Sdk\Exception\MailerConfigurationException at construction. MAILER_BASE_URL is optional: it defaults to the hosted API (https://mailer.mosaiqo.com/api/v1), so hosted users only set the token; self-hosted users override it. An explicitly empty or api.mailer.test placeholder base URL still throws, instead of silently sending to a dead host.

Mail transport (MAIL_MAILER=mailer)

The package registers a mailer mail driver, so you can route Laravel's Mail facade (and notifications, queued mailers, etc.) through the platform /send API without changing any mailing code.

Add a mailer entry to config/mail.php:

and select it:

Now every send flows through the API:

The transport maps the message to a single /send call (one recipient) or a /send/batch call (multiple recipients), reading the subject, HTML body and text body off the message.

Sending with a stored template

To render a platform template by slug instead of inline HTML, set the template headers on the underlying Symfony message from your Mailable. The transport then sends a template payload ({to, template, variables}) and ignores the inline subject/body:

Attachments

Attachments on a Mailable / Symfony message are mapped onto the /send attachments field and delivered by the platform. The behavior is driven by mailer-sdk.mail.attachments (env MAILER_MAIL_ATTACHMENTS):

Mode Behavior
send (default) Map each attachment to {filename, content_type, content(base64)} and send it. An unnamed attachment gets the filename attachment plus an extension inferred from its media type (e.g. attachment.pdf).
fail Throw Mailer\Sdk\Exception\UnsupportedFeatureException — the pre-1.4 fail-loud behavior for apps that never want attachments to leave through this transport.
ignore Log a warning and send the message without the attachments.

Platform limits (validated server-side, one guard duplicated client-side):

Behavior & limitations

The platform /send API is intentionally narrow; the transport adapts to it with explicit, documented behavior rather than silent surprises.

Notification channel

The SDK also registers a mailer notification channel, so a Notification can deliver through the platform /send API by returning ['mailer'] from via() and defining toMailer($notifiable).

toMailer() returns a Mailer\Sdk\Laravel\Mail\MailerMessage for full control. Inline mode uses subject()/html()/text():

Template mode renders a stored template with per-recipient variables:

Recipient routing precedence: an explicit MailerMessage::to() wins, then routeNotificationFor('mailer'), then routeNotificationFor('mail'), then a public $email property on the notifiable.

Other return types are accepted too: a plain /send payload array is used directly (its to/idempotency_key keys are honored, and an attachments key passes through to the API — see Attachments above for shape and limits), and an Illuminate\Contracts\Mail\Mailable is rendered to its subject + HTML only (its attachments are NOT carried over) — return a MailerMessage for templates, a text part or an explicit idempotency key, or the array form for attachments.

The outcome semantics mirror the transport: a suppressed recipient is not a failure — a Mailer\Sdk\Laravel\Events\MessageSuppressed event is dispatched and the send is skipped — while quota / sending-domain / any other API error is rethrown so Laravel marks the notification failed and retries per your queue policy.

A complete notification:

Facade

The package registers a Mailer facade (auto-registered via package discovery) that proxies the same container-bound MailerClient singleton — no separate configuration is needed:

Contributing / Development

Tests run entirely against a Guzzle MockHandler — no network access required.

For how this package is split out of the monorepo into its own repository, tagged with SemVer and published to Packagist, see PUBLISHING.md.


All versions of mailer-php with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
guzzlehttp/guzzle Version ^7
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package mosaiqo/mailer-php contains the following files

Loading the files please wait ...