Appearance
PHP SDK
The Stayblox PHP SDK (stayblox/stayblox-php) handles the Stayblox side of your app so you can focus on your integration. It provides the OAuth install flow, the Developer GraphQL API client, request-signature verification, and the inbox messaging modules. It is a Laravel package.
Use it when you build your app in PHP. If you build in another language, talk to the same public surface directly: the OAuth install flow, the GraphQL Developer API, and the signing scheme.
Installation
bash
composer require stayblox/stayblox-phpIt requires PHP 8.4+ and Laravel 13, and auto-registers through Laravel package discovery: it adds the install-storage migration and the stayblox.signed middleware alias.
Modules
Stayblox\Core: OAuth install, install storage, the Developer API client, and signature verification.Stayblox\Inbox: inbound and outbound messaging for channel-provider apps.
Core
OAuth install
OAuthClient speaks the OAuth install flow. Build the consent URL, then exchange the returned code for a per-install token and webhook secret.
php
use Stayblox\Core\OAuth\OAuthClient;
$oauth = new OAuthClient($clientId, $clientSecret, 'https://admin.stayblox.com');
// 1. Redirect the host to consent:
return redirect()->away($oauth->authorizeUrl($redirectUri, ['provide_inbox_channel'], $state));
// 2. On your callback, exchange the code for a token:
$token = $oauth->exchange($request->query('code'), $redirectUri);
// $token->accessToken, $token->scopes, $token->webhookSecretPersist the result with InstallRepository, keyed by the team slug. Learn the slug from currentApp:
php
use Stayblox\Core\Api\DeveloperApiClient;
use Stayblox\Core\Installs\Install;
use Stayblox\Core\Installs\InstallRepository;
$api = new DeveloperApiClient('https://admin.stayblox.com/developer/api/2026-01/graphql');
$app = $api->currentApp(new Install(['access_token' => $token->accessToken]));
(new InstallRepository)->store($app['teamSlug'], $token->accessToken, $token->webhookSecret, $token->scopes);Developer API client
DeveloperApiClient::query() runs any GraphQL query authenticated as the install:
php
$data = $api->query($install, 'query { currentApp { id name teamSlug } }');Verifying signed requests
Stayblox signs the requests it sends to your app (for example the message_send command) with the install's webhook secret. Put those routes behind the stayblox.signed middleware. It verifies the HMAC on the raw body and binds the resolved install to the request:
php
Route::post('/webhooks/message-send', SendController::class)->middleware('stayblox.signed');
// in the controller:
$install = $request->attributes->get('stayblox_install');See Signing & security for the scheme.
Inbox
For channel-provider apps, the Inbox module carries messages both ways.
Inbound: guest message to Stayblox
Forward a message you received from your provider to Stayblox:
php
use Stayblox\Inbox\InboxApiClient;
use Stayblox\Inbox\Dto\InboundMessage;
$client = new InboxApiClient('https://admin.stayblox.com/developer/api/2026-01/graphql');
$client->inboundMessageCreate($install, new InboundMessage(
channel: 'messenger',
externalThreadId: $threadId,
senderIdentifier: $senderId,
body: $text,
externalMessageId: $providerMessageId,
contactHints: ['firstName' => 'Dana', 'avatarUrl' => 'https://...'],
));Report delivery and read receipts with messageStatusUpdate($install, $providerMessageId, 'delivered').
Outbound: Stayblox to your provider
Stayblox POSTs a signed message_send command to your endpoints.message_send URL. Put that route behind stayblox.signed, then let MessageSendReceiver parse it and call your send handler:
php
use Stayblox\Inbox\MessageSendReceiver;
use Stayblox\Inbox\Dto\OutboundMessage;
use Stayblox\Inbox\Dto\SendResult;
Route::post('/webhooks/message-send', function (Request $request) {
$install = $request->attributes->get('stayblox_install');
$response = (new MessageSendReceiver)->handle(
$request->json()->all(),
function (OutboundMessage $message) use ($install): SendResult {
// Call your provider's send API here.
try {
$providerId = $myProvider->send($message->externalThreadId, (string) $message->body);
return SendResult::sent($providerId);
} catch (\Throwable $e) {
return SendResult::failed($e->getMessage());
}
},
);
return response()->json($response);
})->middleware('stayblox.signed');OutboundMessage is the normalized reply (recipient, body, attachments, settings). SendResult::sent() and SendResult::failed() map to the JSON Stayblox reads back.
DTOs
InboundMessage,InboundResult: the inbound injection payload and its result.OutboundMessage,SendResult: the normalized outbound reply and your send outcome.ChannelCaps: the channel capabilities you declared in your manifest. Branch on capabilities, never on channel identity.
Provider logic stays in your app
The SDK gives you the normalized Stayblox interfaces. Your provider bindings (the Messenger, WhatsApp, or SMS API calls, their auth, and message rendering) live in your app. See the reference app for a complete example.