Official PHP SDK for the Sensei Partner API. Build integrations with Sensei's complete gamification and user engagement platform.
- PHP 8.1 or higher
- Guzzle HTTP client 7.0+
- Laravel 10+ (optional, for framework integration)
composer require sensei/partner-sdkThe SDK uses two authentication levels depending on who performs the action:
| Auth Type | When to Use | Resources |
|---|---|---|
| API Key | Partner/admin operations | users.signupAndLink, products, subscriptions, analytics, dashboard |
| User Token | User-owned actions | guilds, alliances, messages, trustScore, userStripeConnect |
// 1. PARTNER CLIENT (API Key) - for admin operations
$partnerClient = PartnerClient::create([
'api_key' => 'sk_live_xxx',
]);
// Create user and get their token
$result = $partnerClient->users->signupAndLink([
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'SecurePass123!',
]);
$userToken = $result['token'];
// 2. USER CLIENT (Bearer Token) - for user-owned actions
$userClient = PartnerClient::create([
'bearer_token' => $userToken,
'tenant' => 'your-tenant-slug',
]);
// User creates their own guild (they become owner)
$guild = $userClient->guilds->create(['name' => 'My Guild']);
// User sends messages
$userClient->messages->startConversation([...]);
// User gives trust reactions
$userClient->trustScore->giveReaction([...]);use Sensei\PartnerSDK\Configuration;
use Sensei\PartnerSDK\PartnerClient;
// Create configuration
$config = new Configuration(
apiKey: 'sk_live_your_api_key_here'
);
// Create client
$client = new PartnerClient($config);
// Get dashboard overview
$dashboard = $client->dashboard->overview();
// List products
$products = $client->products->all();
// Create a subscription
$subscription = $client->subscriptions->create([
'user_id' => 123,
'product_id' => 456,
'pricing_tier_id' => 789,
]);The SDK includes full Laravel support with auto-discovery.
Publish the config file:
php artisan vendor:publish --tag=sensei-partner-configSet your credentials in .env:
SENSEI_PARTNER_API_KEY=sk_live_your_api_key_here
SENSEI_PARTNER_BASE_URL=https://api.senseitemple.comuse Sensei\PartnerSDK\Laravel\Facades\SenseiPartner;
// Get dashboard stats
$stats = SenseiPartner::dashboard()->overview();
// List all products
$products = SenseiPartner::products()->all();
// Get analytics
$revenue = SenseiPartner::analytics()->revenue([
'start_date' => '2024-01-01',
'end_date' => '2024-12-31',
]);use Sensei\PartnerSDK\PartnerClient;
class DashboardController extends Controller
{
public function __construct(private PartnerClient $senseiPartner)
{
}
public function index()
{
return $this->senseiPartner->dashboard->overview();
}
}Manage formations, services, and digital products.
// List products with pagination
$products = $client->products->all(['per_page' => 20]);
// Get a specific product
$product = $client->products->get(123);
// Create a formation (course)
$formation = $client->products->createFormation([
'title' => 'My Course',
'description' => 'Course description',
'price' => 9900, // cents
]);
// Add modules and lessons
$module = $client->products->createModule($formationId, [
'title' => 'Module 1',
'description' => 'First module',
]);
$lesson = $client->products->createLesson($formationId, $moduleId, [
'title' => 'Lesson 1',
'content' => 'Lesson content...',
]);
// Manage pricing tiers
$tiers = $client->products->pricingTiers($productId);
$tier = $client->products->createPricingTier($productId, [
'name' => 'Premium',
'price' => 4900,
'interval' => 'month',
]);Manage customer subscriptions.
// List subscriptions
$subscriptions = $client->subscriptions->all();
// Create subscription
$subscription = $client->subscriptions->create([
'user_id' => 123,
'product_id' => 456,
'pricing_tier_id' => 789,
]);
// Cancel subscription
$client->subscriptions->cancel($subscriptionId);
// Pause/Resume
$client->subscriptions->pause($subscriptionId, '2024-02-01');
$client->subscriptions->resume($subscriptionId);
// Change plan
$client->subscriptions->changePlan($subscriptionId, $newPricingTierId);
// Apply coupon
$client->subscriptions->applyCoupon($subscriptionId, 'DISCOUNT20');
// Check access
$access = $client->subscriptions->checkAccess($userId, $productId);Manage your customers and students.
// =====================================
// User Creation & Authentication
// =====================================
// Create user and link to your tenant (signup)
// This creates the user AND returns an auth token for immediate use
$result = $client->users->signupAndLink([
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'SecurePassword123!',
// Optional: specify which guild to auto-join
'faction_id' => 123,
]);
// Returns:
// - token: User's auth token for subsequent requests
// - user: User data (id, name, email, avatar, etc.)
// - guild: Guild the user joined (if any)
// - tenant: Tenant information
// Login existing user and link to tenant
$result = $client->users->loginAndLink([
'email' => 'john@example.com',
'password' => 'SecurePassword123!',
]);
// Returns same structure as signupAndLink
// =====================================
// User Management
// =====================================
// List users
$users = $client->users->all();
// Search users
$results = $client->users->search('john@example.com');
// Get user details
$user = $client->users->get($userId);
// Get user's subscriptions
$subscriptions = $client->users->subscriptions($userId);
// Get user's progress
$progress = $client->users->progress($userId, $productId);
// Manage user tags
$client->users->addTag($userId, 'vip');
$client->users->removeTag($userId, 'trial');
// Export users
$export = $client->users->export('csv', ['segment_id' => 123]);Access statistics and generate reports.
// Dashboard overview
$overview = $client->dashboard->overview();
// Revenue stats
$revenue = $client->dashboard->revenue();
$mrr = $client->dashboard->mrr();
$arr = $client->dashboard->arr();
// Subscriber metrics
$subscribers = $client->dashboard->subscribers();
$growth = $client->dashboard->subscriberGrowth();
// Analytics
$analytics = $client->analytics->overview([
'start_date' => '2024-01-01',
'end_date' => '2024-12-31',
]);
// Cohort analysis
$cohorts = $client->analytics->cohorts();
// Retention
$retention = $client->analytics->retention();
// Create custom report
$report = $client->analytics->createReport([
'name' => 'Monthly Revenue Report',
'metrics' => ['revenue', 'subscribers', 'churn'],
'granularity' => 'month',
]);Manage payments, refunds, and invoices.
// List payments
$payments = $client->payments->all();
// Get payment
$payment = $client->payments->get($paymentId);
// Create refund
$refund = $client->payments->refund($paymentId);
// Partial refund
$refund = $client->payments->partialRefund($paymentId, 1000, 'Customer request');
// Invoices
$invoices = $client->payments->invoices();
$invoice = $client->payments->invoice($invoiceId);
$client->payments->sendInvoice($invoiceId);
// Coupons
$coupons = $client->payments->coupons();
$coupon = $client->payments->createCoupon([
'code' => 'SUMMER20',
'discount_percent' => 20,
'expires_at' => '2024-08-31',
]);
// Balance
$balance = $client->payments->balance();Manage your Stripe Connect integration.
// Get account status
$status = $client->stripeConnect->status();
// Get onboarding URL
$onboarding = $client->stripeConnect->onboardingUrl(
returnUrl: 'https://myapp.com/stripe/return',
refreshUrl: 'https://myapp.com/stripe/refresh'
);
// Check if fully onboarded
if ($client->stripeConnect->isFullyOnboarded()) {
// Ready to accept payments
}
// Get balance
$balance = $client->stripeConnect->balance();
// Bank accounts
$accounts = $client->stripeConnect->bankAccounts();
$client->stripeConnect->addBankAccount([
'account_number' => '...',
'routing_number' => '...',
]);Alliances are federations of guilds that can cooperate, share treasuries, and compete in wars.
// =====================================
// Alliance Management
// =====================================
// List all alliances
$alliances = $client->alliances->all();
// Create an alliance
$alliance = $client->alliances->create([
'name' => 'The Federation',
'description' => 'United guilds',
'founder_guild_id' => 123,
'max_guilds' => 10,
'requires_approval' => true,
]);
// =====================================
// Membership
// =====================================
// Invite a guild to join
$client->alliances->invite($allianceId, $guildId);
// Apply to join an alliance
$client->alliances->apply($allianceId, $guildId, 'We want to join!');
// Accept/reject applications
$client->alliances->acceptMember($allianceId, $membershipId);
$client->alliances->rejectMember($allianceId, $membershipId);
// Leave or kick guilds
$client->alliances->leave($allianceId, $guildId);
$client->alliances->kick($allianceId, $membershipId);
// Promote/demote guilds
$client->alliances->setRole($allianceId, $membershipId, 'officer'); // member, officer, leader
// =====================================
// Treasury
// =====================================
// Get treasury balance
$treasury = $client->alliances->treasury($allianceId);
// Contribute to treasury
$client->alliances->contribute($allianceId, $guildId, 1000, 'Monthly contribution');
// Propose expense (may require vote)
$client->alliances->proposeExpense($allianceId, 5000, 'New guild hall');
// Vote on expense
$client->alliances->voteOnExpense($allianceId, $transactionId, $guildId, true);
// =====================================
// Alliance Wars
// =====================================
// Declare war on another alliance
$client->alliances->declareWar($myAllianceId, $enemyAllianceId);
// Accept/decline war (defender)
$client->alliances->acceptWar($allianceId, $warId);
$client->alliances->declineWar($allianceId, $warId);
// Check war status
$status = $client->alliances->warStatus($allianceId);
// Get war leaderboard
$leaderboard = $client->alliances->warLeaderboard($allianceId, $warId);The Trust Score system allows users to build reputation through weighted voting.
// =====================================
// User Trust Reactions
// =====================================
// Give a positive trust reaction (endorsement)
$result = $client->trustScore->giveReaction([
'trustee_uuid' => 'user-uuid-here',
'trust_score' => 5, // 0 to 5
'reaction_type' => 'recommendation',
'comment' => 'Great mentor, highly recommend!',
]);
// Give a negative trust reaction (requires proof of interaction)
$result = $client->trustScore->giveReaction([
'trustee_uuid' => 'user-uuid-here',
'trust_score' => -3, // -5 to 0
'negative_category' => 'no_delivery',
'negative_reason' => 'Paid for service but never received it',
'interaction_type' => 'service',
'interaction_id' => 123,
]);
// Get user's trust score breakdown
$breakdown = $client->trustScore->getUserBreakdown('user-uuid');
// Get my weekly stats (reactions given/remaining)
$stats = $client->trustScore->getMyStats();
// Get reactions I've received
$reactions = $client->trustScore->getReactionsReceived();
// Check if I can give negative vote to a user
$eligibility = $client->trustScore->checkNegativeVoteEligibility('user-uuid');
// Respond to a negative vote I received
$client->trustScore->respondToNegativeVote($reactionId, 'My response explanation...');
// =====================================
// Guild Trust Score
// =====================================
// Get guild's trust score
$score = $client->trustScore->getGuildTrustScore($guildId);
// Vote on a guild
$client->trustScore->voteOnGuild($guildId, [
'reaction' => 'positive',
]);
$client->trustScore->voteOnGuild($guildId, [
'reaction' => 'negative',
'negative_reason' => 'Inactive moderation',
]);
// =====================================
// Alliance Trust Score
// =====================================
// Get alliance's trust score
$score = $client->trustScore->getAllianceTrustScore($allianceId);
// Vote on an alliance
$client->trustScore->voteOnAlliance($allianceId, [
'reaction' => 'positive',
]);
// Get level weights (higher levels = more influence)
$weights = $client->trustScore->getLevelWeights();Allow your tenant's users to become sellers and receive payments for services, events, formations, mentoring, etc.
Important: This resource requires a user token (from signupAndLink or loginAndLink), not the partner API key.
// =====================================
// Setup: Create client with user token
// =====================================
// First, get a user token via signup or login
$result = $partnerClient->users->signupAndLink([
'name' => 'Seller Name',
'email' => 'seller@example.com',
'password' => 'SecurePassword123!',
]);
$userToken = $result['token'];
// Create a new client instance with the user's token
$userClient = PartnerClient::create([
'bearer_token' => $userToken, // User token, not API key
'base_url' => 'https://api.senseitemple.com/api',
'tenant' => 'your-tenant-slug',
]);
// =====================================
// Seller Onboarding Flow
// =====================================
// Step 1: Start Stripe Connect onboarding
$response = $userClient->userStripeConnect->onboard([
'country' => 'FR', // 2-letter country code
'business_type' => 'individual', // 'individual' or 'company'
// 'company_name' => 'My Company', // Required if business_type is 'company'
]);
// Response:
// - message: "Stripe Connect account created"
// - account_id: "acct_xxxxx"
// - onboarding_url: "https://connect.stripe.com/setup/..."
// Redirect user to complete Stripe verification
header('Location: ' . $response['data']['onboarding_url']);
// Step 2: Check onboarding status (after user returns)
$status = $userClient->userStripeConnect->status();
// Response:
// - connected: true/false
// - onboarded: true/false (verification complete)
// - account_id: "acct_xxxxx"
// - status: Account capabilities status
// - requirements: Pending verification requirements
// =====================================
// Seller Dashboard & Earnings
// =====================================
// Get Stripe Express Dashboard link
$dashboard = $userClient->userStripeConnect->dashboard();
// Response: { dashboard_url: "https://connect.stripe.com/express/..." }
// Get account balance
$balance = $userClient->userStripeConnect->balance();
// Response:
// - available: [{ amount: 5000, currency: 'eur' }]
// - pending: [{ amount: 1500, currency: 'eur' }]
// =====================================
// Helper Methods
// =====================================
// Quick check if user can receive payments
if ($userClient->userStripeConnect->canReceivePayments()) {
// Show "Create paid service" button
} else {
// Show "Connect Stripe" button
}
// Refresh onboarding link (if expired)
$refresh = $userClient->userStripeConnect->refresh();
// Response: { onboarding_url: "..." }
// Disconnect Stripe account
$userClient->userStripeConnect->disconnect();Enable Single Sign-On for seamless authentication between your platform and Sensei Temple. Implements OAuth 2.0 with mandatory PKCE (RFC 7636) for enhanced security.
// =====================================
// SSO Settings Management
// =====================================
// Get current SSO settings and stats
$response = $client->sso->getSettings();
// $response['settings'] - SSO configuration
// $response['stats'] - Usage statistics
// Enable SSO for your tenant
// If no credentials exist, they will be auto-generated
// WARNING: client_secret is only shown ONCE when first enabled!
$result = $client->sso->enable();
if (isset($result['settings']['client_secret'])) {
// Save this immediately - it won't be shown again!
$clientSecret = $result['settings']['client_secret'];
}
// Disable SSO
$client->sso->disable();
// Toggle SSO
$client->sso->toggle(true); // or false
// Rotate client secret only (keeps client_id)
// WARNING: client_secret is only shown ONCE!
$result = $client->sso->regenerateSecret();
$newSecret = $result['settings']['client_secret']; // Save immediately!
// Manage redirect URIs
$client->sso->addRedirectUri('https://newapp.com/callback');
$client->sso->removeRedirectUri('https://oldapp.com/callback');
$client->sso->setRedirectUris([
'https://app1.com/callback',
'https://app2.com/callback',
]);
// Get SSO statistics
$stats = $client->sso->getStats();
// $stats['stats']['total_connections']
// $stats['stats']['active_users']
// $stats['stats']['last_30_days']
// =====================================
// OAuth 2.0 Flow Implementation
// =====================================
// Step 1: Generate PKCE parameters
$pkce = \Sensei\PartnerSDK\Resources\Sso::generatePkce();
// Store $pkce['code_verifier'] in session for later use!
session(['pkce_verifier' => $pkce['code_verifier']]);
// Step 2: Build authorization URL and redirect user
$authUrl = $client->sso->buildAuthorizationUrl(
clientId: 'sensei_your_client_id',
redirectUri: 'https://myapp.com/auth/callback',
codeChallenge: $pkce['code_challenge'],
scopes: ['openid', 'profile', 'email'],
state: bin2hex(random_bytes(16)) // CSRF protection
);
// Redirect user to $authUrl
// Step 3: Handle callback - Exchange code for tokens
$tokens = $client->sso->exchangeCode(
code: $request->get('code'),
clientId: 'sensei_your_client_id',
clientSecret: 'your_client_secret',
redirectUri: 'https://myapp.com/auth/callback',
codeVerifier: session('pkce_verifier')
);
// $tokens['access_token']
// $tokens['refresh_token'] (if enabled)
// $tokens['expires_in']
// Step 4: Get user info
$userInfo = $client->sso->getUserInfo($tokens['access_token']);
// $userInfo['sub'] - User ID
// $userInfo['name'] - (if profile scope)
// $userInfo['email'] - (if email scope)
// Refresh token when expired
$newTokens = $client->sso->refreshToken(
refreshToken: $tokens['refresh_token'],
clientId: 'sensei_your_client_id',
clientSecret: 'your_client_secret'
);
// Revoke token (logout)
$client->sso->revokeToken($tokens['access_token'], 'access_token');
$client->sso->revokeToken($tokens['refresh_token'], 'refresh_token');
// Get OpenID Connect discovery URL
$discoveryUrl = $client->sso->getDiscoveryUrl();
// Returns: https://api.senseitemple.com/.well-known/openid-configuration- Always use PKCE - The SDK enforces PKCE with S256 method (mandatory)
- Use state parameter - Protect against CSRF attacks
- Store tokens securely - Never expose tokens in URLs or logs
- Short-lived access tokens - Default 15 min, max 1 hour
- Use HTTPS redirect URIs - Required in production
- Rotate secrets regularly - Use
regenerateSecret()periodically
Manage your API keys for integrations.
// List API keys
$keys = $client->apiKeys->all();
// Create new key
$key = $client->apiKeys->create([
'name' => 'Production Key',
'permissions' => ['products:read', 'subscriptions:write'],
]);
// Regenerate secret
$newKey = $client->apiKeys->regenerate($keyId);
// Get usage stats
$usage = $client->apiKeys->usage($keyId);
// Disable key
$client->apiKeys->disable($keyId);Configure webhook endpoints.
// List webhooks
$webhooks = $client->webhooks->all();
// Create webhook
$webhook = $client->webhooks->create([
'url' => 'https://myapp.com/webhooks/sensei',
'events' => ['subscription.created', 'subscription.cancelled', 'payment.completed'],
]);
// Test webhook
$client->webhooks->test($webhookId);
// Get available events
$events = $client->webhooks->eventTypes();
// Verify webhook signature
$isValid = \Sensei\PartnerSDK\Resources\Webhooks::verifySignature(
payload: $request->getContent(),
signature: $request->header('X-Sensei-Signature'),
secret: $webhookSecret
);Handle compliance requirements.
// GDPR
$gdprStatus = $client->compliance->gdprStatus();
// Data export request
$export = $client->compliance->requestDataExport($userId);
// Data deletion request
$deletion = $client->compliance->requestDeletion($userId, 'User requested');
// Consent management
$client->compliance->recordConsent($userId, 'marketing', true);
// DPA (Data Processing Agreement)
$dpa = $client->compliance->getCurrentDpa();
$client->compliance->signDpa($dpaId, [
'signer_name' => 'John Doe',
'signer_email' => 'john@company.com',
'company_name' => 'My Company',
]);
// Tax settings
$taxSettings = $client->compliance->taxSettings();
$client->compliance->updateTaxSettings([
'vat_number' => 'FR12345678901',
'country' => 'FR',
]);
// Validate VAT number
$validation = $client->compliance->validateVatNumber('FR12345678901', 'FR');Manage your partner profile.
// Get profile
$profile = $client->profile->get();
// Update profile
$client->profile->updateProfile([
'business_name' => 'My Business',
'description' => 'We provide...',
]);
// Upload logo
$client->profile->uploadLogo('/path/to/logo.png');
// Settings
$settings = $client->settings->all();
$client->settings->set('email_notifications', true);
// Security
$client->settings->enable2fa();
$sessions = $client->settings->sessions();
$client->settings->revokeAllSessions();The SDK uses cursor-based pagination with a PaginatedResponse helper:
// Get first page
$products = $client->products->all(['per_page' => 20]);
// Access items
foreach ($products->items() as $product) {
echo $product['title'];
}
// Check pagination info
echo "Page {$products->currentPage()} of {$products->totalPages()}";
echo "Total: {$products->total()} items";
// Navigate pages
if ($products->hasMorePages()) {
$nextPage = $products->nextPage();
}
// Iterate through all pages automatically
foreach ($products->all() as $product) {
// Automatically fetches next pages as needed
processProduct($product);
}The SDK throws specific exceptions for different error types:
use Sensei\PartnerSDK\Exceptions\AuthenticationException;
use Sensei\PartnerSDK\Exceptions\ValidationException;
use Sensei\PartnerSDK\Exceptions\NotFoundException;
use Sensei\PartnerSDK\Exceptions\RateLimitException;
use Sensei\PartnerSDK\Exceptions\ServerException;
try {
$product = $client->products->get(999999);
} catch (NotFoundException $e) {
// Product not found (404)
echo "Product not found: " . $e->getMessage();
} catch (ValidationException $e) {
// Validation error (422)
foreach ($e->getErrors() as $field => $messages) {
echo "{$field}: " . implode(', ', $messages);
}
} catch (AuthenticationException $e) {
// Auth error (401/403)
echo "Authentication failed: " . $e->getMessage();
} catch (RateLimitException $e) {
// Rate limited (429)
echo "Rate limited. Retry after: " . $e->getRetryAfter() . " seconds";
} catch (ServerException $e) {
// Server error (5xx)
echo "Server error: " . $e->getMessage();
}$config = new Configuration(
apiKey: 'sk_live_xxx', // Your API key
bearerToken: null, // Alternative: Bearer token
baseUrl: 'https://api.senseitemple.com',
timeout: 30, // Request timeout (seconds)
connectTimeout: 10, // Connection timeout (seconds)
maxRetries: 3, // Max retry attempts
verifySSL: true, // SSL verification
retryOnRateLimit: true, // Auto-retry on 429
);Or from array:
$client = PartnerClient::create([
'api_key' => 'sk_live_xxx',
'base_url' => 'https://api.senseitemple.com',
'timeout' => 30,
]);For testing, use test mode API keys (sk_test_xxx):
$config = new Configuration(
apiKey: 'sk_test_your_test_key'
);
// Check mode
if ($config->isTestMode()) {
echo "Running in test mode";
}- Documentation: https://docs.senseitemple.com
- API Reference: https://api.senseitemple.com/docs
- Support: support@senseitemple.com
MIT License - see LICENSE file for details.