Download the PHP package millionsend/millionsend-php without Composer
On this page you can find all versions of the php package millionsend/millionsend-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download millionsend/millionsend-php
More information about millionsend/millionsend-php
Files in millionsend/millionsend-php
Package millionsend-php
Short Description Official PHP SDK for MillionSend — a self-hostable, Resend-compatible email API.
License MIT
Homepage https://github.com/MillionSend/millionsend-php
Informations about the package millionsend-php
millionsend-php
Official PHP SDK for MillionSend — a self-hostable, Resend-compatible email API on AWS SES.
The API is wire-compatible with Resend, and this SDK deliberately mirrors the
shape of resend-php, so migrating is
mostly a find-and-replace: swap the factory (and, for a self-hosted instance,
point the base URL at it).
Install
Requires PHP 8.1+.
Quickstart
Configuration
With just an API key the client talks to MillionSend Cloud (https://api.millionsend.com).
A self-hosted instance sets its origin via baseUrl or MILLIONSEND_BASE_URL. Plain http:// is only
accepted for loopback hosts (localhost, 127.0.0.1, ::1); any other http:// URL
throws InvalidArgumentException at construction, since the API key is sent as a bearer
header. Pass 'allowInsecureHttp' => true to talk to a non-TLS instance elsewhere (e.g.
inside a private network).
Payloads
Payloads are plain arrays and go on the wire as-is — every key you pass is sent, in
snake_case exactly as resend-php documents it (reply_to, scheduled_at,
first_name, …). The camelCase spellings this SDK has always accepted keep working
and are renamed on the way out (replyTo → reply_to, scheduledAt → scheduled_at,
topicId → topic_id, firstName → first_name, segmentId → segment_id,
previewText → preview_text, and so on per resource below). A key that is present
with a null value is sent as JSON null, which is how you clear a nullable field;
a key you leave out stays off the wire.
Successful calls return the decoded JSON body as an associative array.
Errors
Every non-2xx response throws MillionSend\Exceptions\ErrorException. Its
getErrorName() is a stable snake_case code you can branch on
(validation_error, not_found, restricted_api_key, sending_paused, all_recipients_suppressed, …).
Client-side and transport failures (a request that never reached the API) throw
the same exception with getStatusCode() returning null.
emails->send() and batch->send() throw a 422 all_recipients_suppressed when every
to recipient is on the suppression list or has opted out of the send's topic_id.
Resources
Emails
Every send field is supported: from, to, subject, html, text, cc, bcc,
reply_to, scheduled_at, tags, topic_id, attachments, headers and
template. to/cc/bcc/reply_to accept a string or an array. Options:
idempotency_key (or idempotencyKey) sets the Idempotency-Key header.
Batch
batch_validation (or batchValidation) sets the x-batch-validation header. In
strict mode one invalid email fails the whole batch; in permissive mode the valid
ones are sent and the rest come back in the response's errors[] as
[{index, message}].
Contacts
Contacts are team-global: one record per email address, shared by every broadcast and segment. Address them by id or by email.
Contact properties
Topics
Broadcasts
Targeting is an optional segment_id and/or topic_id — omit both to send to
every contact on the team.
Segments
Same methods as resend-php's ->segments, but membership is dynamic: a segment
is a saved filter over the team's contacts (the filter field is the MillionSend
extension). Omit it — or set it to null on update — for a manual segment whose
members come from contacts->segments->add().
Suppressions
Domains
Webhooks
During the overlap every delivery carries both signatures (new first, then previous,
space-separated in webhook-signature), so a receiver holding either verifies.
Subscribable events include email.* plus the contact and suppression events:
contact.created, contact.updated, contact.deleted, contact.unsubscribed,
contact.resubscribed, contact.topic_opt_in, contact.topic_opt_out,
suppression.added, suppression.removed.
API keys
Templates
Templates are addressable by id or alias.
Deliverability (MillionSend extension)
The account-level deliverability score over the trailing window. Scores are
0-10 with one decimal; score/band are null until there is enough data.
Usage (MillionSend extension)
Migrating from Resend
Method names, nesting, options (idempotency_key, batch_validation) and payloads
match resend-php; snake_case payloads pass through to the wire untouched. Notes:
- No audiences. Contacts are team-global, so there is no
->audiencesresource and noaudience_idparams — drop the audience id and the calls map straight over. (The API keeps/audiences/...routes as a compatibility shim; they are not part of this SDK.)->segmentskeeps Resend's method names; membership is a dynamicfilterrather than a static list. - Not offered here (no MillionSend endpoint):
->contacts->imports,->contacts->segments->list(), emailshare()/metrics(),->emails->attachments/->receiving,->webhooks->eventsand the localverify()helper,->domains->claims,->broadcasts->recipients()/->clickedLinks,->apiKeys->update(), and the->events/->logs/->automationsservices. Domaintls/capabilitiespass through and are answered with 422. - MillionSend extensions (no Resend counterpart): segment
filter,->contacts->batch,->contacts->preferencesLink(),->webhooks->rotate(),->emails->getInsights(),->emails->remove(),->deliverability,->usage.
Calling endpoints the SDK does not wrap yet
The transport is public as $ms->http. It adds auth and the User-Agent, sends the
Idempotency-Key header on POST, and maps errors to ErrorException exactly like the
wrapped methods do:
License
MIT — see LICENSE.