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

Rest Api Laravel Package

sendpulse/rest-api

Official PHP client for the SendPulse REST API, supporting API key and OAuth auth. Manage bulk email campaigns, transactional SMTP, SMS, CRM contacts and chatbots through a typed, ergonomic service layer with optional PSR-18 and PSR-16 adapters. Requires PHP 8.3+ and ext-curl/ext-json.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a thin, official REST client — not a framework, not an abstraction layer, not a queue. It gives you Client → typed service facades (emailService(), smtpService(), smsService(), crmService(), chatbotService()) over typed models generated from SendPulse's OpenAPI specs, plus auth/token handling and a typed exception hierarchy. The architectural bet is therefore narrow and defensible: you own the orchestration (queues, retries, idempotency, templates, consent, suppression lists, reconciliation); the SDK owns wire format and auth. That is the right split for a TPM to approve, because it keeps vendor lock-in at the transport seam. It is a poor fit only if a stakeholder expects the SDK to deliver deliverability management, bounce handling, or campaign analytics beyond the raw endpoint responses — none of that is here.

Integration feasibility. Low friction on paper: composer require sendpulse/rest-api, zero runtime dependencies beyond ext-curl/ext-json, PSR-18 HTTP and PSR-16 cache adapters available as optional drop-ins, and a documented Laravel integration page. The PSR-18/PSR-16 hooks are the deciding feature for a Laravel shop — they let you pass the framework's HTTP client (keeping logging, tracing, Http::fake() in tests) and a shared cache for tokens instead of the default FileTokenStorage. The real gate is the PHP ≥ 8.3 floor, which constrains your Laravel version and therefore your other dependency upgrades.

Technical risk. Three items dominate:

  • A rewrite is one release old. 3.0.0 was a complete BC break (entry point, auth signature, raw get/post/put/patch/delete replaced by facades, new exception hierarchy, storage classes removed). 3.0.1 then fixed CRM and chatbot URL prefixes such that every call to those services previously returned 404, plus path-parameter encoding via rawurlencode(). A bug of that class surviving to a tagged release in generated code means you should assume other endpoints in the five-service surface are less exercised than the changelog implies.
  • Validation depth is thin. 26 unit tests across five product lines, 117 stars, and zero dependents per Packagist means there is no visible external production usage to borrow confidence from. You are an early adopter, not a follower.
  • Documentation is internally inconsistent. The README states PHP ≥ 8.3, zero runtime dependencies, and a six-class exception hierarchy; the package description still references PHP ≥ 7.1 and a single typed exception. That inconsistency signals the docs weren't fully swept during the 3.0 rewrite — assume the README is authoritative and verify anything else against the source.

Positives that genuinely offset the above: official vendor provenance, MIT license, PHPStan max and PSR-12 compliance, a changelog and upgrade guide that actually exist, and a small enough surface (zero deps, no magic) that forking or replacing it is measured in days, not weeks.

Key questions to get answered before committing:

  1. Is 3.x the stable line, or is a 4.0 already on the roadmap? Pin ^3.0 explicitly and treat majors as manual migrations.
  2. Where do OAuth tokens live in a multi-node, autoscaled deployment? Confirm Psr16TokenStorage against Redis and understand the cache-stampede behavior on the 401-invalidate-and-retry-once path.
  3. Does RateLimitException surface Retry-After / rate-limit headers, or only the status? If not, backoff policy is entirely yours to invent.
  4. Is there a sandbox/test account and are there contract tests against it? If not, you are the integration test suite.
  5. What is the idempotency story for sendSmtpEmail? On NetworkException (transport failure after the request left), how do you determine whether the message was actually delivered — presumably getSmtpEmailInfo('message-id') reconciliation, which means you must persist the message ID yourself.
  6. Does docs/laravel.md ship a service provider/package discovery, or just instructions? Either way, you'll likely write your own binding.
  7. Commercial support path: this is SendPulse account support, not library support — confirm who answers when a 5xx is on their side.
  8. Data residency and PII: contact attributes and consent state — in your DB, in SendPulse address books, or both?

Integration Approach

Stack fit. Target is a Laravel app on PHP 8.3+. Bind Sendpulse\RestApi\Client as a singleton in a service provider, driven by config/env (API key or client credentials, connectTimeout/requestTimeout, cache-backed token storage). Critically, do not let the SDK's types leak into domain code: define your own MessagingGateway interface (e.g. sendTransactional(), syncContact(), createCampaign()) with a SendPulseGateway implementation. This is the one architectural instruction worth enforcing in review — it is what makes a second vendor swap a sprint rather than a quarter, and it confines the SDK's exception hierarchy to a single adapter class.

Migration path. Greenfield: no migration, just the gateway seam from day one. If any 1.x/2.x ApiClient code exists (positional (API_USER_ID, API_SECRET, $storage), raw verb methods, ApiClientException, FileStorage/SessionStorage/MemcachedStorage), use a strangler: introduce the gateway interface, wrap the legacy calls behind it, then swap the implementation to the 3.x Client, then delete the old code and its storage classes. docs/upgrading.md reportedly covers this; validate it against a single service before trusting it across all five.

Compatibility. Treat PHP 8.3 as the hard floor and plan the Laravel/Symfony/other-dependency implications as part of this workstream, not after it. Pin "sendpulse/rest-api": "^3.0" — never * or >=2 — given the rewrite cadence. Configure a dependency-update policy: patch auto-merge, minors require a look at the changelog, majors manual with the upgrade guide. Wire Psr18Adapter over Laravel's HTTP client and Psr16TokenStorage over the configured cache store; leave FileTokenStorage for local development only.

Sequencing.

  1. Credential + smoke test. Walk the sandbox with the two or three services you actually plan to use. Explicitly hit CRM and chatbot once each — those were the 404 endpoints in 3.0.0.
  2. Token storage on shared cache, verified across at least two app instances, including forced token expiry.
  3. Gateway interface + fixtures. Record real responses and build contract tests; this is the asset that survives a vendor swap or an SDK upgrade.
  4. First channel: transactional SMTP. Lowest blast radius, reversible, small payloads, and it exercises auth, exceptions, and the reconciliation path you'll need everywhere else.
  5. Then bulk email / address books — campaigns are asynchronous and higher-stakes; by now your runbook and alerting exist.
  6. CRM and chatbot last. Newest, least-exercised code path in the package, and the one with the known recent bug history.
  7. Observability before go-live on channel two: per-service success/error counters keyed by exception class, token-refresh events, and a dead-letter queue for sends that ended in NetworkException or ProtocolException.

Operational Impact

Maintenance. Low but non-zero burden, skewed toward the first year. Official provenance, MIT, active releases and a real changelog are what you want; a brand-new major is what you don't. Budget roughly one planned upgrade per year plus a re-verification of the endpoints you actually call after each minor — because models are generated from OpenAPI specs, a minor can change typed model shapes without looking like a breaking change in a changelog. Keep the dependency behind your gateway so an upstream surprise is a one-file fix.

Support. There is no commercial support for the library itself; "official" means the vendor maintains it, not that you can open a ticket about it. Your on-call team owns it. Mitigate by pinning, watching releases, and knowing that the fork escape hatch is cheap here — MIT, a few thousand lines, zero runtime dependencies. Estimate the fork-or-replace option at days of engineering; that number is what makes this a low-risk bet despite the low adoption signals.

Scaling. The SDK is stateless except for tokens, so scale-out risk concentrates in exactly two places. First, token storage: FileTokenStorage on an ephemeral container filesystem means every replica refreshes independently and you invite auth storms — use Psr16TokenStorage on shared Redis in anything beyond a single box. Second, 429 and 5xx handling: RateLimitException gets you the status, but backoff, jitter, and per-channel concurrency limits are yours. Defaults of 10s connect / 30s request are fine for transactional calls; bulk campaign creation with binary attachments needs a larger requestTimeout and belongs in queued jobs, not request cycles.

Failure modes and how to route them.

  • AuthException (401) → the SDK invalidates the cached token and retries once automatically. Understand that this can mean a request was transmitted twice; keep send operations as close to idempotent as the API allows and persist message IDs so you can reconcile.
  • ForbiddenException (403) → tariff or permission restriction. This is a plan/procurement problem, not a code defect. Route to alerting with a human owner, never to a retry loop. Note this cleanly split out of AuthException only in 3.0.1 — good signal, recent change.
  • RateLimitException (429) → retry with exponential backoff and jitter at your gateway layer.
  • ApiException (other 4xx/5xx) → httpStatus and rawBody are available; log both, retry 5xx only.
  • NetworkException / ProtocolException → the ambiguous ones. The request may have succeeded. These must terminate in a reconciliation job, not a blind retry. ProtocolException now also fires when the API returns a JSON primitive instead of an object, which is a sensible guard but means malformed vendor responses surface as failures rather than silent empty arrays — make sure your handlers don't treat that as "no data."
  • A single catch (SendPulseExceptionInterface $e) gives you a catch-all for metrics and dead-lettering without enumerating six classes in every call site — use it at the gateway boundary, and the specific classes only for routing.

Ramp-up. A mid-level PHP engineer is productive within a day: the README examples are copy-pasteable, docs/authentication.md, docs/exceptions.md, docs/testing.md, docs/laravel.md, and docs/upgrading.md cover the paths that matter, and the typed facades remove guesswork about endpoint shapes. The genuinely expensive knowledge is domain-side, not SDK-side — SendPulse address books, tariffs, campaign state machines, and deliverability semantics — plus the fixtures, reconciliation logic, and runbook the SDK deliberately doesn't provide. Plan roughly one sprint to take a first channel to production including tests, observability, and on-call documentation; the second and third channels are a fraction of that cost once the gateway and exception-routing pattern exist.

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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc