fluxchat/sdk

SDK · Stable

PHP SDK

v0.3.0 · Stable

Official FluxChat SDK for PHP 8.1+. Works with Laravel, Symfony, WordPress, and plain PHP. cURL under the hood, typed exceptions, no framework dependency.

SourceContributed by @benjaminmugangu — PHP SDK

Installation

terminal
composer require fluxchat/sdk

Create a client

The base URL defaults to https://api.fluxchat-corp.com/api/v2 — production. Pass it explicitly to target dev.

client.php
<?php
use FluxChat\FluxChat;

$client = new FluxChat(getenv('FLUXCHAT_API_KEY'));

ask()

Send a message and get the assistant's reply. Pass context to inject real-time data the bot treats as a priority source of truth, above the knowledge base. A sessionId keeps multi-turn history without persisting a conversation.

ask.php
$response = $client->ask(
    'Quels sont vos horaires ?',
    context: 'Utilisateur : Alice, Plan : Pro',
    sessionId: $sessionId,
);

echo $response['reply'];

Human handoff (support thread)

When the bot can't help, hand the visitor to a human. This creates a real support ticket in the organization's dashboard — and unlike a contact form, the conversation stays open in the same thread: the visitor polls it, the agent answers into it.

handoff.php
$support = $client->support();

// 1. Hand off — with the same $sessionId you pass to ask(), the bot's side
//    of the conversation is copied into the ticket.
$ticket = $support->escalate(
    'Jordan Mbeki',
    'jordan@example.com',
    'Mon virement est bloqué depuis hier.',
    $sessionId,
);

// 2. Follow the thread: the e-mail proves the ticket is theirs.
$thread = $support->thread($ticket['ticketId'], 'jordan@example.com');
foreach ($thread['messages'] as $m) {
    echo $m['role'] . ' : ' . $m['content'] . PHP_EOL;  // bot | visitor | agent
}

// 3. Let them reply into it.
$support->reply($ticket['ticketId'], 'jordan@example.com', 'La référence est 4821.');
  • Ownership is the e-mail. A wrong e-mail and a non-existent ticket both return 404, deliberately — a guessed ticket id reveals nothing. The lookup is also scoped to the organization behind your API key.
  • Polled, not pushed. There is no socket on the public surface. 5s is the cadence the official widget uses and what the route's limits are sized for: 60 reads/min, 30 replies/min, 5 escalations/min.
  • Statuses: open → in_progress → resolved → closed. A reply to a resolved ticket reopens it; a closed one refuses the write (403) rather than swallowing a message nobody will read.
  • Requires the organization's plan to include supportTickets (403 otherwise).

Knowledge base

Create, update and delete articles. Write operations need a key with the bot:write scope, or an admin JWT.

knowledge.php
$kb = $client->knowledge($jwtToken);

$article = $kb->create('Délais de livraison', 'Livraison sous 48 h en RDC.');
$kb->update($article['id'], ['content' => 'Livraison sous 24 h à Kinshasa.']);
$kb->delete($article['id']);

Errors

Every failure is typed: an API error carries the HTTP status and the server's message, a network error wraps the transport failure, and a config error is raised before any request leaves.

errors.php
use FluxChat\Exceptions\FluxChatApiException;
use FluxChat\Exceptions\FluxChatNetworkException;

try {
    $support->thread($ticketId, 'someone@else.com');
} catch (FluxChatApiException $e) {
    // 404 both when the ticket does not exist and when the e-mail does not
    // own it — deliberately indistinguishable.
    echo $e->getStatusCode() . ' ' . $e->getMessage();
} catch (FluxChatNetworkException $e) {
    echo 'transport failure: ' . $e->getMessage();
}