Search by

sendity / laravel-server

chsch

Self-hosted Sendity server implementation for Laravel

Package info

gitlab.com/sendity/server/laravel

Issues

pkg:composer/sendity/laravel-server

Statistics

Installs: 103

Dependents: 0

Suggesters: 0

Stars: 0

v0.3.0-beta.8 2026-10-26 15:33 UTC

README

Reusable Laravel package for running the Sendity API in a Laravel runtime.

composer require sendity/laravel-server

Boundary

This is a PHP/Laravel package. It is not the public Sendity website and it does not own Docker-era hosted-app wiring.

It owns:

  • AuthRequest creation and status endpoints.
  • inbound channel webhook endpoints:
    • email receives raw message/rfc822 bodies and delegates DKIM/MIME/code extraction to sendity/email-channel;
    • non-email channels continue to use their package-specific JSON adapters.
  • webhook signature and replay validation.
  • JWT issuing and JWKS publication.
  • realtime/broadcasting auth metadata for AuthRequest status updates.

It intentionally does not own:

  • the <x-sendity /> Blade wrapper for customer applications;
  • browser UI defaults such as SENDITY_CLIENT_SCRIPT_URL or SENDITY_VERIFY_URLS;
  • the hosted marketing/customer website;
  • Docker/Traefik deployment manifests.

Compatibility

  • PHP: >=8.2
  • Laravel components: ^12.0|^13.0
  • Testbench: ^10.0|^11.0

Important environment variables

SENDITY_ROUTE_PREFIX=sendity
SENDITY_JWT_ALGORITHM=RS256
SENDITY_JWT_PRIVATE_KEY_BASE64=
SENDITY_JWT_PUBLIC_KEY_BASE64=
SENDITY_JWT_ISSUER=https://sendity.io
SENDITY_DEFAULT_TOKEN_TTL=600
SENDITY_AUTH_REQUEST_TTL=300
SENDITY_WEBHOOK_SECRET=
SENDITY_EMAIL_MAX_MESSAGE_BYTES=262144
SENDITY_EMAIL_MAX_EXTRACTED_CODES=5
SENDITY_PHONE_RECIPIENT=+4915888620026
SENDITY_RCS_SERVICE_ID=sendity_agent@rbm.goog
SENDITY_APP_PHONE_SMS_FALLBACK_ALLOWED=false
SENDITY_BROADCASTING_ENABLED=true

TTL values are application configuration. They are not accepted as client request payload fields.

AuthRequest creation returns one server-owned verification_action. The browser may provide bounded localized email_body and phone_text templates. The server substitutes (Host) only in email copy and (Code) in phone copy, selects the configured recipient, and builds the complete action URL. WhatsApp and SMS use the same localized instruction: send the message, then return to the original browser to continue. Phone templates containing host placeholders or website links fall back to the safe English instruction, preventing competing link previews. For a Twilio/Google RCS setup, recipient remains the SMS fallback number, optional rcs_recipient contains the configured RBM agent ID, and url contains the complete sms: deep link with service_id and body. Browser clients display only the primary recipient and use the URL unchanged.

The default phone text tells the user to send the message and return to their browser to continue. Custom phone templates must include (Code) and omit website addresses and (Host). Email templates still require (Host).

Polling can report pending, received, or verified. Verification rejections such as failed DKIM checks or a disallowed SMS fallback are exposed through latest_verification_rejection and broadcast as .verification.rejected.

Hosted sendity.io exposes the public Sendity API through the website Laravel process under /api/*. A direct self-hosted runtime can use the package default /sendity/* prefix or configure another prefix.

Direct WhatsApp Cloud API

The phone channel supports direct Meta WhatsApp webhooks, with strict provider-observed phone evidence. The Laravel server verifies the raw signature and account/phone metadata at GET|POST /{route-prefix}/incoming-messages/phone/meta. BSUIDs and arbitrary contact cards are never treated as phone numbers.

When Meta is fully configured, phone actions add transport: "whatsapp" and an HTTPS wa.me URL. Apps permitting SMS also receive sms_fallback: {recipient, url}. The client lets the user switch deliberately and preserves the choice, URL and QR across browser return. Disabled/incomplete Meta configuration retains the existing action.

See the setup guide for protected configuration, publication and hidden-number disclosure handling.