Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sendyphp Laravel Package

jacobbennett/sendyphp

SendyPHP is a simple PHP client for the Sendy email newsletter API, making it easy to manage subscribers, lists, and campaigns from your Laravel or PHP application with clean, readable methods.

Deep Wiki
Context7

Technical Evaluation

  • What it is: A thin, synchronous cURL wrapper over Sendy's form-encoded HTTP API (/api/subscribe, /api/unsubscribe, /api/subscription-status, /api/delete). Authentication is a static api_key in the request body — no OAuth, no SDK versioning, no request signing.
  • Architecture fit: Only fits if Sendy is, or will remain, the system of record for list membership. It is a transport adapter, not an integration layer: no domain model, no events, no retry policy, no idempotency keys. In a Laravel codebase it occupies the same slot as a hand-rolled Http::asForm()->post(). The value it adds is naming and a config file, not capability.
  • Integration feasibility: High. MIT licensed, minimal dependency footprint, drop-in Composer install. If a service provider/facade ships with your version, wiring is a config publish plus three env vars; if not, a short container binding suffices. A working spike against a staging Sendy instance should take under a day.
  • Technical risk:
    • Staleness (primary): last release January 2021. No declared support for PHP 8.2/8.3 or Laravel 10/11. Expect deprecation noise at minimum, and plausibly hard failures on dynamic properties under PHP 8.x.
    • Stringly-typed contract: responses are arrays with status as '1'/'0' strings plus human-readable message text. Callers must string-match to distinguish "already subscribed" from "invalid email" from "transport failure." This is the largest source of production bugs in wrappers of this kind.
    • No resilience primitives: no configurable timeouts, no backoff, no circuit breaking, no rate-limit awareness. Sendy's SES-derived throttling surfaces as opaque failures.
    • Credential handling: the API key travels in the body of every request. A misconfigured base URL (e.g., a staging host promoted by copy-paste) leaks a full-privilege key.
    • Blast radius: low. The package is roughly 200 LOC and MIT; worst case is vendoring or replacing it, not a migration.
  • Key questions:
    1. Which Sendy version is deployed (4/5/6)? Endpoint behavior and batch-subscribe support differ materially.
    2. Single list or many? Most versions bind one list ID per instance; multi-list requires per-list instantiation and is easy to get wrong.
    3. Do we need campaign creation/scheduling, or only subscriber lifecycle? This package likely covers only the latter.
    4. Is Sendy a strategic platform or a legacy holdover? The low opportunity score (1.14) is consistent with a shrinking surface — thin wrappers around maintenance-mode software rarely grow into platform investments.
    5. What are our PHP and Laravel target versions for the next 12 months?

Verdict: acceptable as a sealed adapter behind our own interface, not as a runtime dependency we assume will be maintained. Budget a fork from day one.

Integration Approach

  • Stack fit: Native to Laravel/PHP. Composer install, publish config, set SENDY_INSTALLATION_URL, SENDY_API_KEY, SENDY_LIST_ID. Stateless — no queue, cache, or database requirements of its own.
  • Mandatory wrapping: Do not let controllers or jobs call the class directly. Define a SubscriptionGateway interface (subscribe, unsubscribe, status, delete) with a concrete SendyGateway and a NullGateway for tests. This is the core architectural play: it makes the stale dependency replaceable in one file and lets us move to a modern ESP without touching call sites.
  • Compatibility path: Pin the package, then run a PHP 8.x pass (static analysis plus a staging smoke test). If it breaks, fork under our namespace or rewrite as a ~100-line HTTP client — both are cheaper than negotiating upstream, which has been dormant since 2021.
  • Sequencing:
    1. Spike against staging Sendy; capture exact success and error response bodies as a fixture set.
    2. Build the gateway interface plus a normalizer mapping Sendy's status/message pairs to a typed result (Subscribed, AlreadySubscribed, InvalidEmail, Unsubscribed, TransportError, Unknown).
    3. Move all calls into queued jobs with explicit timeout and retry policy, plus a dead-letter path.
    4. Dual-write against the current list source, reconcile counts, then cut over.
    5. Add a scheduled reconciliation command for drift.
  • Sequencing caveat: double opt-in is enforced by Sendy, not this package. If consent state matters — it does — the gateway must model "pending confirmation" explicitly rather than treating subscribe as subscribed.

Operational Impact

  • Maintenance: Effectively self-maintained. No upstream releases since January 2021, a small community (133 stars), and issues likely unanswered. Treat the fork as owned code: named owner, dependency-review entry, and an annual "is Sendy still right" checkpoint.
  • Support: Community-only. The escalation path is our own engineers reading 200 lines of PHP. Fine for a low-blast-radius adapter; not fine if list management becomes revenue-critical without a fallback.
  • Scaling: The ceiling is Sendy plus SES, not this package. Every call is a blocking round trip to the Sendy host; subscribe-heavy flows (bulk import, large webhook fan-in) need batching where the deployed version supports it, or a capped worker pool. Treat Sendy host capacity and SES sending quotas as the real constraints.
  • Failure modes to instrument:
    • Transport failures (DNS, TLS, timeout) indistinguishable from API rejections unless explicitly checked.
    • Sendy returning an HTML error page from a broken install, parsed as a "successful" HTTP 200.
    • status => '0' meaning "already subscribed," misread as an error — causing retry storms and duplicate side effects.
    • Wrong list ID yielding apparent success with a silent no-op.
    • API key rotation with no graceful degradation: every subscribe fails simultaneously.
    • SES sandbox-to-production drift producing intermittent rejections.
  • Observability gap: the package emits no events or logs. Wrap every call with structured logging (endpoint, list, latency, normalized outcome, correlation ID) and alert on error rate and p95 latency to the Sendy host.
  • Ramp-up: Very low for the package — any PHP developer reads it in under 30 minutes. The real onboarding cost is Sendy's operational model (self-hosted PHP/MySQL, SES configuration, double opt-in semantics); budget days, not hours, for whoever owns that instance.
  • Security/PII: Subscriber emails and custom fields transit our own infrastructure. Confirm TLS-only on the Sendy host, a key scoped to a single installation and held in a secret manager, and email redaction in logs.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings